summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/canvas
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/html/canvas
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/canvas')
-rw-r--r--testing/web-platform/tests/html/canvas/META.yml6
-rw-r--r--testing/web-platform/tests/html/canvas/README.md1
-rw-r--r--testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.basics.html62
-rw-r--r--testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.delete.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.drawings.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.missingargs.html141
-rw-r--r--testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree-ref.html9
-rw-r--r--testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.exists.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.invalid.args.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.prototype.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.shared.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.exists.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.extend.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.prototype.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.replace.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.unique.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.2dstate.html102
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.readonly.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.reference.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled.pngbin0 -> 219 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.hex.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.zero.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.hex.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.zero.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.pngbin0 -> 209 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.clear.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.copy.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-atop.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-in.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-out.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-over.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.lighter.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-atop.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-in.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-out.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-over.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.xor.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvas.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvascopy.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvaspattern.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.default.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.fill.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.image.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.imagepattern.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.invalid.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.range.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.pngbin0 -> 209 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.casesensitive.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.clear.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.darker.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.default.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.get.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.highlight.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.nullsuffix.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.over.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.unrecognised.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.pngbin0 -> 207 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.pngbin0 -> 222 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.pngbin0 -> 208 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.pngbin0 -> 222 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.pngbin0 -> 222 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.basics.html61
-rw-r--r--testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.delete.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.drawings.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.missingargs.html140
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.3arg.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.5arg.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.alpha.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.animated.gif.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.broken.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.canvas.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.clip.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.composite.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.floatsource.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.emptysrc.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.immediate.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.nosrc.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.reload.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.removedsrc.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedest.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedir.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativesource.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonexistent.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html335
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nowrap.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.null.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.path.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.1.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.2.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.svg.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.transform.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.paragraph.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.path.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.path.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html53
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html59
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.transparency.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.currentcolor.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.default.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.solid.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.transparent.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidstring.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidtype.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.basic.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.changed.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.pngbin0 -> 112 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.pngbin0 -> 207 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.pngbin0 -> 207 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.pngbin0 -> 112 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.pngbin0 -> 207 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.pngbin0 -> 207 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.pngbin0 -> 112 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.pngbin0 -> 207 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.pngbin0 -> 207 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.system.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.empty.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.pngbin0 -> 219 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.pngbin0 -> 219 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.pngbin0 -> 396 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.pngbin0 -> 256 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.outside.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.pngbin0 -> 248 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.solid.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.pngbin0 -> 229 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.1.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.2.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.3.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.compare.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.pngbin0 -> 112 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.return.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.type.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.update.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.front.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.top.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.equal.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside2.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside3.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.negative.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html100
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch2.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch3.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.1.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.2.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.3.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.animated.gif.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.canvas.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.image.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.type.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.crosscanvas.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.broken.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.emptysrc.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.immediate.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.nosrc.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.reload.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.removedsrc.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent-but-loading.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nosrc.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.null.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.string.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.undefined.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zeroheight.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zerowidth.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas2.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image1.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image2.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.case.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.empty.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.undefined.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.nonexistent.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zeroheight.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zerowidth.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.transparency.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colormix.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.default.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html68
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html66
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html57
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html56
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html66
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html123
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html57
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html107
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.tentative.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html129
-rw-r--r--testing/web-platform/tests/html/canvas/element/filters/2d.filter.value.html55
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.beginLayer-options.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full.html23
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside-expected.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-expected.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside.html23
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside-expected.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow-expected.html17
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.exceptions-are-no-op.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation-expected.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter-expected.html17
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending-expected.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow-expected.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite-expected.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow-expected.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending-expected.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html55
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite-expected.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html55
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow-expected.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow-expected.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow-expected.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow-expected.html53
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow-expected.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-restore.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.endLayer.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-beginLayer-restore.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-endLayer.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.layer-rendering-state-reset-in-layer.html56
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.toBlob.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.createPattern.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.drawImage.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.getImageData.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.putImageData.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.toDataURL.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-expected.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters-expected.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas-expected.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style-expected.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style.html25
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-endLayer.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-save.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.restore.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save-beginLayer.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_reset_restore.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_restore.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.butt.html60
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.closed.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.invalid.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.open.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.round.html76
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.square.html60
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.valid.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cross.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.defaults.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.fill.noop.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.invalid.strokestyle.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.bevel.html79
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.closed.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.invalid.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.miter.html70
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.open.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.parallel.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.round.html77
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.valid.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.acute.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.exceeded.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.invalid.html59
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.lineedge.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.obtuse.html51
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.rightangle.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.valid.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.within.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.union.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.basic.html62
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.invalid.html59
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.scaledefault.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.transformed.html68
-rw-r--r--testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.valid.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/README.md1
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001-ref.htm22
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001.htm26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001-ref.htm32
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001.htm35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow-ref.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001-ref.htm11
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001.htm32
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/canvas-with-padding.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false-ref.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false-ref.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false-ref.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false-ref.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false.html18
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/getContextAttributes.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false-ref.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false.html13
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false-ref.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false.html17
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html203
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self.html17
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html11
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_crossorigin.sub.html61
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_html_image.html268
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_1.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_with_foreign_object_does_not_taint.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none.tentative.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none.tentative.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height.tentative.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap.tentative.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob-ref.html10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob.tentative.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none.tentative.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none.tentative.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-ref.html12
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height.tentative.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.tentative.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect-ref.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect.tentative.html25
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_complexshapes_ispointInpath_001.htm31
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_focus_drawFocusIfNeeded_AAPI_001-manual.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_001.html66
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_002.html68
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_003.html69
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_004.html88
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_005.html88
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math-ref.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/2d.fillStyle.parse.current.notrendered.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/canvas_colorsandstyles_createlineargradient_001.htm59
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-expected.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation-expected.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html66
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html65
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html62
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html77
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html60
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html58
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html55
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/image-smoothing/imagesmoothing.html119
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-ImageBitmap-close.html89
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html170
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-video-resize.html62
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/common.sub.js168
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-blob-invalidtype.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html67
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage-closed.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html87
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html121
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation_none.html61
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html73
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-in-worker-transfer.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html239
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-serializable.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html53
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-worker.js17
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation-expected.html18
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-expected.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped-expected.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imagebitmap-replication-exif-orientation.html146
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_1.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_2.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_3.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_4.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_5.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_6.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_7.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_8.jpgbin0 -> 1227 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/serialize-worker.js3
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/transfer-worker.js3
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/imagebitmap/worker-onmessage-noop.js3
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001-ref.htm11
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001.htm37
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_a.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_ref.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/line-styles/setLineDash.html104
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_001.htm60
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002-ref.htm27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002.htm34
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors-expected.html11
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/shadows/shadowBlur_gaussian_tolerance.1.html191
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected-ref.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected.html24
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch-ref.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.condensed.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.expanded.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-condensed.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-expanded.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.normal.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-condensed.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-expanded.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-condensed.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-expanded.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001-ref.htm22
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001.htm33
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.state.saverestore.imageSmoothingEnabled.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.zero.size.canvas.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001-ref.htm11
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001.htm42
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/transformations/2d.transformation.getTransform.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001-ref.html21
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001-ref.htm11
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001.htm31
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/transformations/transform_a.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/transformations/transform_ref.html16
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1-expected.htm10
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1.htm14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2-expected.htm14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2.htm15
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3-expected.htm13
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3.htm16
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4-expected.htm14
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4.htm17
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/ImageData-fidelity.html126
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageData.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html53
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html70
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html57
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3.js283
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/imagedata-no-color-settings-crash.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000CC.pngbin0 -> 575 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000FF.pngbin0 -> 562 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000CCCC.pngbin0 -> 560 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000FFFF.pngbin0 -> 554 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000CC.pngbin0 -> 575 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000FF.pngbin0 -> 562 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000CCCC.pngbin0 -> 575 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000FFFF.pngbin0 -> 562 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-0.7333-0-0.svg3
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-1-0-0.svg3
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000CC.pngbin0 -> 620 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000FF.pngbin0 -> 607 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000CCCC.pngbin0 -> 605 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000FFFF.pngbin0 -> 599 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000CC.pngbin0 -> 620 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000FF.pngbin0 -> 607 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000CCCC.pngbin0 -> 620 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000FFFF.pngbin0 -> 607 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-BE000000.jpgbin0 -> 55590 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-FF000000.jpgbin0 -> 55590 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.mp4bin0 -> 3275 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.webmbin0 -> 604 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.mp4bin0 -> 3275 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.webmbin0 -> 605 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-p3d65.pngbin0 -> 5912 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-rec2020.pngbin0 -> 6136 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-srgb.pngbin0 -> 5319 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.avifbin0 -> 529 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.bmpbin0 -> 1738 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.icobin0 -> 1742 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.pngbin0 -> 5319 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.webpbin0 -> 252 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.avifbin0 -> 330 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.bmpbin0 -> 1738 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.gifbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.icobin0 -> 1742 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.jpgbin0 -> 898 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.pngbin0 -> 163 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.svg6
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.webpbin0 -> 208 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_opaque.pngbin0 -> 3164 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_transparent.pngbin0 -> 3175 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_opaque.pngbin0 -> 3262 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_transparent.pngbin0 -> 3271 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_opaque.pngbin0 -> 3338 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_transparent.pngbin0 -> 3347 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_opaque.pngbin0 -> 3144 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_transparent.pngbin0 -> 3153 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_opaque.pngbin0 -> 3165 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_transparent.pngbin0 -> 3174 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_opaque.pngbin0 -> 3265 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_transparent.pngbin0 -> 3272 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_opaque.pngbin0 -> 3339 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_transparent.pngbin0 -> 3348 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_opaque.pngbin0 -> 3147 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_transparent.pngbin0 -> 3153 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_opaque.pngbin0 -> 2868 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_transparent.pngbin0 -> 2876 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_opaque.pngbin0 -> 2867 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_transparent.pngbin0 -> 2672 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_opaque.pngbin0 -> 3173 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_transparent.pngbin0 -> 3177 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_opaque.pngbin0 -> 3250 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_transparent.pngbin0 -> 3255 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_opaque.pngbin0 -> 3325 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_transparent.pngbin0 -> 3331 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_opaque.pngbin0 -> 3132 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_transparent.pngbin0 -> 3136 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_opaque.pngbin0 -> 2853 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_transparent.pngbin0 -> 2857 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.mp4bin0 -> 1600 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.svg3
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.webmbin0 -> 604 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000CC.pngbin0 -> 243 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000FF.pngbin0 -> 230 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000CCCC.pngbin0 -> 228 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000FFFF.pngbin0 -> 222 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000.svg3
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000CC.pngbin0 -> 243 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000FF.pngbin0 -> 230 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.mp4bin0 -> 1600 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.webmbin0 -> 605 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000CCCC.pngbin0 -> 243 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000FFFF.pngbin0 -> 230 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.3.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.4.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.5.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.6.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.default.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.empty.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.end.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.negative.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonempty.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonfinite.html76
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.1.html53
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.2.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.1.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.2.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.3.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.4.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.5.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.3.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.4.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.5.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.6.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zeroradius.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.1.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.2.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.1.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.2.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.3.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.negative.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.nonfinite.html74
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.scale.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve1.html59
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve2.html58
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.end.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.start.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.transformation.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.1.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.2.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.beginPath.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.basic.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.nonfinite.html108
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.scaled.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.shape.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.1.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.2.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.empty.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.intersect.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.unaffected.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.2.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.empty.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.newline.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.nextpoint.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.ellipse.basics.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.unaffected.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.add.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.1.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.2.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.3.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.initial.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.arc.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.1.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.2.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.html65
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bezier.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bigarc.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.edge.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.empty.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.nonfinite.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.outside.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.subpath.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.3.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.4.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.unclosed.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.winding.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInStroke.scaleddashes.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.invalid.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.multi.path.html48
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.basic.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nextpoint.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.details.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.basic.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.multiple.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.newsubpath.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.nonfinite.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.basic.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.nonfinite.html56
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.scaled.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.shape.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.basic.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.closed.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.2.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.negative.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.newsubpath.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.nonfinite.html56
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.selfintersect.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.winding.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.3.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.4.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.5.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.6.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.single.argument.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompoint.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompoint.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompoint.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompoint.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompoint.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompoint.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompoint.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompoint.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompoint.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.double.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.badinput.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.closed.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.2.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.3.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.4.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.negative.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.newsubpath.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.nonfinite.html115
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.1.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.2.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noargument.html49
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noarugment.html49
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.selfintersect.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.winding.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.3.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.4.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.5.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.6.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.empty.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.arc.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.closed.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.corner.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.curve.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.line.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.rect.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale1.html53
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale2.html55
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.skew.html69
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.unaffected.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.union.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.basic.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.changing.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.multiple.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create.and.resize.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.basic.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.initial.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.this.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.type.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.zero.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.basic.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.double.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.initial.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.large.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.negative.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.nonfinite.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.round.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.this.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.type.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.zero.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.basic.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.clamp.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.double.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.invalid.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.large.crash.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.length.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonfinite.html74
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonpremul.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.alpha.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.cols.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rgb.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rows.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.range.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.rounding.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.negative.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.outside.html85
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.size.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.type.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.unaffected.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.zero.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.clamp.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.bounds.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.basics.html111
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.bounds.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.nan.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.properties.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.readonly.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.round.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.set.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.string.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.undefined.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.basic.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.created.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.cross.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.outside.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.zero.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.modified.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.nonfinite.html108
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.null.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.path.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unaffected.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.wrongtype.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.basic.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation.html20
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc.html23
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit-expected.html22
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip.html23
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.direction.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.fill_style.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.filter.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_kerning.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_stretch.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_variant_caps.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_alpha.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_composite_operation.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_enabled.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_quality.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.letter_spacing.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_cap.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash_offset.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_join.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_width.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.miter_limit.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_blur.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_color.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_x.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_y.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.stroke_style.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_align.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_baseline.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_rendering.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.transformation_matrix.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.word_spacing.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.basic.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.path.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalLR.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalRL.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.1.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.initial.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.invalid.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.valid.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.basic.html28
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.changed.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.removed.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.initial.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.invalid.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.valid.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.initial.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.invalid.html66
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.valid.html49
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high-manual.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high.pngbin0 -> 246 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low-manual.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low.pngbin0 -> 1586 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.basic.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.1.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.2.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.1.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.2.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.3.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.3.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.blur.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.x.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.y.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.1.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.2.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.basic.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.scale.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.section.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.2.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeX.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeY.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveX.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveY.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.outside.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.1.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.2.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.basic.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.1.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.2.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.1.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.2.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.3.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.align.default.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.align.invalid.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.align.valid.html39
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.default.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.invalid.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.valid.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.center.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.ltr.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.rtl.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.left.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.right.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.ltr.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.rtl.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.alphabetic.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.bottom.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.hanging.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.ideographic.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.middle.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.top.html47
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic-manual.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic.pngbin0 -> 1137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.NaN.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.bound.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.fontface.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large-manual.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.pngbin0 -> 1137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.negative.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.small.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.zero.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl-manual.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl.pngbin0 -> 1137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.unaffected.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.html44
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.notinpage.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.repeat.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.kern.consistent-manual.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.basic.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.end.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.nonspace.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.other.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.space.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.start.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic-manual.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic.pngbin0 -> 1634 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.unaffected.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.absolute.spacing.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.font-relative.spacing.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.with.uppercase.html57
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontStretch.settings.html81
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontVariant.settings.html78
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.invalid.spacing.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.measure.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.direction.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.rtl.text.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.textAlign.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.nonfinite.spacing.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.textRendering.settings.html80
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.change.font.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.measure.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.default.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.basic.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex2.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.family.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.invalid.html71
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.default.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.system.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.tiny.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.relative_size.html29
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.font.weight.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1.html18
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps2.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6.html19
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.actualBoundingBox.html61
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.advances.html52
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.baselines.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-low-ascent.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-zero-descent.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights.html45
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-reduced-ascent.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-zero-descent.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.ahem.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.basic.html42
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.empty.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.space.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/2d.text.setFont.mathFont.html26
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/direction-inherit-rtl.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/direction-ltr.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/direction-rtl.html31
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/parent-style-relative-units.html23
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/reference/direction-default-ref.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/text/reference/direction-rtl-ref.html27
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.bitmap.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.clip.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.fillStyle.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.font.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalAlpha.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineCap.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineJoin.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineWidth.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.miterLimit.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.path.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowBlur.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowColor.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetX.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetY.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stack.html35
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stackdepth.html36
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.strokeStyle.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textAlign.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textBaseline.html40
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.transformation.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.underflow.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.order.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.direction.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.nonfinite.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.radians.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrap.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrapnegative.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.zero.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.basic.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.large.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.multiple.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.negative.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.nonfinite.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.zero.html43
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.multiple.html34
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.nonfinite.html109
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.skewed.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.identity.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.multiply.html33
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.nonfinite.html109
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.skewed.html54
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.basic.html32
-rw-r--r--testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.nonfinite.html41
-rw-r--r--testing/web-platform/tests/html/canvas/element/video/2d.video.invalid.html30
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.html58
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.shadow.html62
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.strokeText.html59
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3.html38
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.srgb.html37
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.p3.canvas.html50
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.with.putImageData.html56
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.jpeg.p3.canvas.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.p3.canvas.html46
-rw-r--r--testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.with.putImageData.html53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.html62
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.worker.js58
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.html141
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.worker.js137
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/META.yml7
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/WEB_FEATURES.yml3
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.getContext.options.any.js46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.html89
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.worker.js84
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.html62
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.worker.js57
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.html141
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.worker.js136
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.html24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.worker.js20
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.html25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.worker.js21
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html328
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.worker.js324
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.svg.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.worker.js47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.worker.js48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.worker.js49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html60
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.pngbin0 -> 219 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.pngbin0 -> 219 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.pngbin0 -> 396 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.pngbin0 -> 256 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.pngbin0 -> 248 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.pngbin0 -> 229 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.worker.js44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.worker.js48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.worker.js48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html101
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.worker.js96
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.colormix.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html69
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js64
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html67
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.worker.js62
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html58
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.worker.js53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html57
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.worker.js52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html67
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.worker.js62
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html124
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js119
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html57
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html110
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html124
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.html49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.worker.js44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html130
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js125
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.html56
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.worker.js51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.worker.js46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.w.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.w.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.html26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.w.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.html25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.w.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside-expected.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.w.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-expected.html26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.html26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.w.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside-expected.html26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.html25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.w.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow-expected.html17
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow-expected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter-expected.html17
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.w.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending-expected.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow-expected.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.w.html56
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.w.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite-expected.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow-expected.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.w.html56
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.w.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.w.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.w.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.w.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.w.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.w.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.w.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending-expected.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.w.html59
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite-expected.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.w.html59
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow-expected.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html58
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow-expected.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.w.html58
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.w.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow-expected.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.w.html58
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.w.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states-expected.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.w.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow-expected.html53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.w.html57
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states-expected.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.w.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow-expected.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.w.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.html57
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.worker.js52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-expected.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters-expected.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.w.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.w.html53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas-expected.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.w.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.w.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style-expected.html24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.w.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex-expected.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.w.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.w.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.w.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html21
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.w.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.w.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.html61
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.worker.js56
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.worker.js47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.html77
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.worker.js72
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.html61
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.worker.js56
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.html80
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.worker.js75
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.worker.js47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.html71
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.worker.js66
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.html78
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.worker.js73
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.worker.js47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.html60
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.worker.js55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.worker.js47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.html63
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.worker.js58
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.html60
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.worker.js55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.html69
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.worker.js64
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.html165
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.w.html337
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.html49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.w.html52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.js48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.w.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.html128
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.worker.js126
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.w.html48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.w.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas-worker-font-load-crash.html19
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.worker.js45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.html80
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.worker.js77
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.resize.html240
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.lowlatency.nocrash.html12
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.html112
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.nocrash.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w.html201
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w.html76
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.html83
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.w.html142
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/transformations/2d.transformation.getTransform.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/manual/wide-gamut-canvas/2d.color.space.p3.convertToBlobp3.canvas.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.html77
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.worker.js72
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.worker.js49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.html48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.worker.js43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.html75
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.worker.js70
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.html60
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.worker.js55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.html59
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.worker.js54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.html109
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.worker.js104
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.html49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.worker.js44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.html29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.worker.js24
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.html66
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.worker.js61
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.html48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.worker.js43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.html51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.worker.js46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.html49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.worker.js44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.html57
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.worker.js52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.html57
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.worker.js52
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.html116
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.worker.js111
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.worker.js45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.pngbin0 -> 205 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.html54
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.worker.js49
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.html56
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.worker.js51
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.html70
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.worker.js65
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.html47
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.worker.js42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.html75
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.worker.js70
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.html86
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.worker.js81
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.pngbin0 -> 221 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.html109
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.worker.js104
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.html25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.w.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.html23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.w.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line-expected.html19
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.w.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.html26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.w.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit-expected.html22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.w.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.w.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip-expected.html14
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.html26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.w.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/set-proprietary-font-names-001-crash.html13
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.html53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.worker.js48
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.html67
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.worker.js62
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.worker.js45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high.pngbin0 -> 246 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low.pngbin0 -> 1586 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.worker.js25
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.pngbin0 -> 206 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.html45
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.worker.js40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.html40
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.pngbin0 -> 1137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.pngbin0 -> 1137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.pngbin0 -> 1137 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.pngbin0 -> 1634 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.html58
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.worker.js53
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.html82
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.worker.js77
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.html79
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.worker.js74
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.html43
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.worker.js38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.html81
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.worker.js76
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.html46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.worker.js41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.html72
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.worker.js67
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.html28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.worker.js23
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html21
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.w.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2-unexpected.html16
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.w.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.w.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.w.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html15
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.w.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.html50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.worker.js46
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.worker.js27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.html26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.html32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.html27
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.worker.js22
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch-ref.html19
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.condensed.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.expanded.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-condensed.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-expanded.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.normal.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-condensed.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-expanded.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-condensed.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-expanded.html30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.html36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.worker.js31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.html37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.worker.js32
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.html41
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.worker.js36
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.html31
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.worker.js26
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.html44
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.worker.js39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.html35
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.worker.js30
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.html110
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.worker.js105
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.html34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.worker.js29
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.html110
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.worker.js105
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.html55
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.worker.js50
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.html33
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.worker.js28
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.html42
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.worker.js37
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.html39
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.worker.js34
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.html38
-rw-r--r--testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.worker.js33
-rw-r--r--testing/web-platform/tests/html/canvas/resources/2x2.pngbin0 -> 1575 bytes
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-frame.css21
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-frame.css.headers1
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-index.css31
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-index.css.headers1
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-spec.css50
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-spec.css.headers1
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-tests.css134
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-tests.css.headers1
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-tests.js221
-rw-r--r--testing/web-platform/tests/html/canvas/resources/canvas-tests.js.headers1
-rw-r--r--testing/web-platform/tests/html/canvas/tools/gentest.py18
-rw-r--r--testing/web-platform/tests/html/canvas/tools/gentest_union.py3
-rw-r--r--testing/web-platform/tests/html/canvas/tools/gentestutils.py369
-rw-r--r--testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py535
-rw-r--r--testing/web-platform/tests/html/canvas/tools/name2dir-canvas.yaml26
-rw-r--r--testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml22
-rw-r--r--testing/web-platform/tests/html/canvas/tools/name2dir.yaml25
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates.yaml80
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates/reftest.html14
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates/reftest_element.html34
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates/reftest_offscreen.html29
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates/reftest_worker.html37
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates/testharness_element.html68
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates/testharness_offscreen.html45
-rw-r--r--testing/web-platform/tests/html/canvas/tools/templates/testharness_worker.js35
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml319
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml232
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml178
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml640
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml469
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/fill-and-stroke-styles.yaml2104
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml680
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml1022
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/line-styles.yaml954
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/path-objects.yaml3403
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/pixel-manipulation.yaml1042
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml286
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml76
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/shadows.yaml1090
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/text.yaml1680
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/the-canvas-state.yaml89
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/transformations.yaml356
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml10
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml/element/meta.yaml539
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml/element/the-canvas-element.yaml143
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml/offscreen/meta.yaml539
-rw-r--r--testing/web-platform/tests/html/canvas/tools/yaml/offscreen/the-offscreen-canvas.yaml269
3913 files changed, 147059 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/canvas/META.yml b/testing/web-platform/tests/html/canvas/META.yml
new file mode 100644
index 0000000000..0f79f25912
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/META.yml
@@ -0,0 +1,6 @@
+spec: https://html.spec.whatwg.org/multipage/canvas.html#2dcontext
+suggested_reviewers:
+ - AmeliaBR
+ - annevk
+ - kenrussell
+ - fserb
diff --git a/testing/web-platform/tests/html/canvas/README.md b/testing/web-platform/tests/html/canvas/README.md
new file mode 100644
index 0000000000..63f2246f2d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/README.md
@@ -0,0 +1 @@
+To update the generated tests, run `wpt update-built --include canvas`.
diff --git a/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.basics.html b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.basics.html
new file mode 100644
index 0000000000..fed4aa61ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.basics.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.basics</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.basics</h1>
+<p class="desc">void methods return undefined</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("void methods return undefined");
+_addTest(function(canvas, ctx) {
+
+_assertSame(ctx.save(), undefined, "ctx.save()", "undefined");
+_assertSame(ctx.restore(), undefined, "ctx.restore()", "undefined");
+_assertSame(ctx.scale(1, 1), undefined, "ctx.scale(1, 1)", "undefined");
+_assertSame(ctx.rotate(0), undefined, "ctx.rotate(0)", "undefined");
+_assertSame(ctx.translate(0, 0), undefined, "ctx.translate(0, 0)", "undefined");
+if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ _assertSame(ctx.transform(1, 0, 0, 1, 0, 0), undefined, "ctx.transform(1, 0, 0, 1, 0, 0)", "undefined");
+}
+if (ctx.setTransform) {
+ _assertSame(ctx.setTransform(1, 0, 0, 1, 0, 0), undefined, "ctx.setTransform(1, 0, 0, 1, 0, 0)", "undefined");
+ _assertSame(ctx.setTransform(), undefined, "ctx.setTransform()", "undefined");
+}
+_assertSame(ctx.clearRect(0, 0, 0, 0), undefined, "ctx.clearRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.fillRect(0, 0, 0, 0), undefined, "ctx.fillRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.strokeRect(0, 0, 0, 0), undefined, "ctx.strokeRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.beginPath(), undefined, "ctx.beginPath()", "undefined");
+_assertSame(ctx.closePath(), undefined, "ctx.closePath()", "undefined");
+_assertSame(ctx.moveTo(0, 0), undefined, "ctx.moveTo(0, 0)", "undefined");
+_assertSame(ctx.lineTo(0, 0), undefined, "ctx.lineTo(0, 0)", "undefined");
+_assertSame(ctx.quadraticCurveTo(0, 0, 0, 0), undefined, "ctx.quadraticCurveTo(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.bezierCurveTo(0, 0, 0, 0, 0, 0), undefined, "ctx.bezierCurveTo(0, 0, 0, 0, 0, 0)", "undefined");
+_assertSame(ctx.arcTo(0, 0, 0, 0, 1), undefined, "ctx.arcTo(0, 0, 0, 0, 1)", "undefined");
+_assertSame(ctx.rect(0, 0, 0, 0), undefined, "ctx.rect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.arc(0, 0, 1, 0, 0, true), undefined, "ctx.arc(0, 0, 1, 0, 0, true)", "undefined");
+_assertSame(ctx.fill(), undefined, "ctx.fill()", "undefined");
+_assertSame(ctx.stroke(), undefined, "ctx.stroke()", "undefined");
+_assertSame(ctx.clip(), undefined, "ctx.clip()", "undefined");
+if (ctx.fillText) {
+ _assertSame(ctx.fillText('test', 0, 0), undefined, "ctx.fillText('test', 0, 0)", "undefined");
+ _assertSame(ctx.strokeText('test', 0, 0), undefined, "ctx.strokeText('test', 0, 0)", "undefined");
+}
+if (ctx.putImageData) {
+ _assertSame(ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0), undefined, "ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0)", "undefined");
+}
+_assertSame(ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+_assertSame(ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white'), undefined, "ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white')", "undefined");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.delete.html b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.delete.html
new file mode 100644
index 0000000000..bfdf94319b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.delete.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.delete</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.delete</h1>
+<p class="desc">window.CanvasRenderingContext2D is Configurable</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("window.CanvasRenderingContext2D is Configurable");
+_addTest(function(canvas, ctx) {
+
+_assertDifferent(window.CanvasRenderingContext2D, undefined, "window.CanvasRenderingContext2D", "undefined");
+_assertSame(delete window.CanvasRenderingContext2D, true, "delete window.CanvasRenderingContext2D", "true");
+_assertSame(window.CanvasRenderingContext2D, undefined, "window.CanvasRenderingContext2D", "undefined");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.drawings.html b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.drawings.html
new file mode 100644
index 0000000000..40038b2191
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.drawings.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.drawings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.drawings</h1>
+<p class="desc">void methods return undefined</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("void methods return undefined");
+_addTest(function(canvas, ctx) {
+
+_assertSame(ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.missingargs.html b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.missingargs.html
new file mode 100644
index 0000000000..2ac3d58f4e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/2d.conformance.requirements.missingargs.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.missingargs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.missingargs</h1>
+<p class="desc">Missing arguments cause TypeError</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Missing arguments cause TypeError");
+_addTest(function(canvas, ctx) {
+
+assert_throws_js(TypeError, function() { ctx.scale(); });
+assert_throws_js(TypeError, function() { ctx.scale(1); });
+assert_throws_js(TypeError, function() { ctx.rotate(); });
+assert_throws_js(TypeError, function() { ctx.translate(); });
+assert_throws_js(TypeError, function() { ctx.translate(0); });
+if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ assert_throws_js(TypeError, function() { ctx.transform(); });
+ assert_throws_js(TypeError, function() { ctx.transform(1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1, 0); });
+}
+if (ctx.setTransform) {
+ assert_throws_js(TypeError, function() { ctx.setTransform(1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1, 0); });
+}
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.createPattern(canvas); });
+assert_throws_js(TypeError, function() { ctx.clearRect(); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.moveTo(); });
+assert_throws_js(TypeError, function() { ctx.moveTo(0); });
+assert_throws_js(TypeError, function() { ctx.lineTo(); });
+assert_throws_js(TypeError, function() { ctx.lineTo(0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.rect(); });
+assert_throws_js(TypeError, function() { ctx.rect(0); });
+assert_throws_js(TypeError, function() { ctx.rect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.rect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arc(); });
+assert_throws_js(TypeError, function() { ctx.arc(0); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1, 0); });
+// (6th argument to arc is optional)
+if (ctx.isPointInPath) {
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(0); });
+}
+if (ctx.drawFocusRing) {
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas, 0); });
+}
+if (ctx.fillText) {
+ assert_throws_js(TypeError, function() { ctx.fillText(); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test'); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeText(); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test'); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.measureText(); });
+}
+assert_throws_js(TypeError, function() { ctx.drawImage(); });
+assert_throws_js(TypeError, function() { ctx.drawImage(canvas); });
+assert_throws_js(TypeError, function() { ctx.drawImage(canvas, 0); });
+// TODO: n >= 3 args on drawImage could be either a valid overload,
+// or too few for another overload, or too many for another
+// overload - what should happen?
+if (ctx.createImageData) {
+ assert_throws_js(TypeError, function() { ctx.createImageData(); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(1); });
+}
+if (ctx.getImageData) {
+ assert_throws_js(TypeError, function() { ctx.getImageData(); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0, 1); });
+}
+if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ assert_throws_js(TypeError, function() { ctx.putImageData(); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0); });
+}
+var g = ctx.createLinearGradient(0, 0, 0, 0);
+assert_throws_js(TypeError, function() { g.addColorStop(); });
+assert_throws_js(TypeError, function() { g.addColorStop(0); });
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree-ref.html b/testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree-ref.html
new file mode 100644
index 0000000000..707bafd320
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Test reference</title>
+<canvas id="canvas"></canvas>
+<script>
+ let canvas = document.getElementById("canvas");
+ let ctx = canvas.getContext("2d");
+ ctx.font = "10px sans-serif";
+ ctx.fillText('Hello, world', 10, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree.html b/testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree.html
new file mode 100644
index 0000000000..cf76967a1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/2d.text-outside-of-the-flat-tree.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Canvas outside the flat tree</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1792860">
+<link rel="match" href="2d.text-outside-of-the-flat-tree-ref.html">
+<div id="host"><canvas id="canvas"></canvas></div>
+<script>
+ let host = document.getElementById("host");
+ // Leaves the canvas un-slotted.
+ let root = host.attachShadow({ mode: "open"});
+ let canvas = document.getElementById("canvas");
+ let ctx = canvas.getContext("2d");
+ ctx.font = "10px sans-serif";
+ ctx.fillText('Hello, world', 10, 10);
+ // Slots the content.
+ root.innerHTML = `<slot></slot>`;
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.exists.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.exists.html
new file mode 100644
index 0000000000..1c44acbd54
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.exists.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.exists</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.exists</h1>
+<p class="desc">The 2D context is implemented</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("The 2D context is implemented");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(canvas.getContext('2d'), null, "canvas.getContext('2d')", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html
new file mode 100644
index 0000000000..f4db40815d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.extraargs.cache</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.extraargs.cache</h1>
+<p class="desc">The 2D context doesn't throw with extra getContext arguments (cached)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("The 2D context doesn't throw with extra getContext arguments (cached)");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(canvas.getContext('2d', false, {}, [], 1, "2"), null, "canvas.getContext('2d', false, {}, [], 1, \"2\")", "null");
+ _assertDifferent(canvas.getContext('2d', 123), null, "canvas.getContext('2d', 123)", "null");
+ _assertDifferent(canvas.getContext('2d', "test"), null, "canvas.getContext('2d', \"test\")", "null");
+ _assertDifferent(canvas.getContext('2d', undefined), null, "canvas.getContext('2d', undefined)", "null");
+ _assertDifferent(canvas.getContext('2d', null), null, "canvas.getContext('2d', null)", "null");
+ _assertDifferent(canvas.getContext('2d', Symbol.hasInstance), null, "canvas.getContext('2d', Symbol.hasInstance)", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html
new file mode 100644
index 0000000000..6ae7f787c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.extraargs.create</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.extraargs.create</h1>
+<p class="desc">The 2D context doesn't throw with extra getContext arguments (new context)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("The 2D context doesn't throw with extra getContext arguments (new context)");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(document.createElement("canvas").getContext('2d', false, {}, [], 1, "2"), null, "document.createElement(\"canvas\").getContext('2d', false, {}, [], 1, \"2\")", "null");
+ _assertDifferent(document.createElement("canvas").getContext('2d', 123), null, "document.createElement(\"canvas\").getContext('2d', 123)", "null");
+ _assertDifferent(document.createElement("canvas").getContext('2d', "test"), null, "document.createElement(\"canvas\").getContext('2d', \"test\")", "null");
+ _assertDifferent(document.createElement("canvas").getContext('2d', undefined), null, "document.createElement(\"canvas\").getContext('2d', undefined)", "null");
+ _assertDifferent(document.createElement("canvas").getContext('2d', null), null, "document.createElement(\"canvas\").getContext('2d', null)", "null");
+ _assertDifferent(document.createElement("canvas").getContext('2d', Symbol.hasInstance), null, "document.createElement(\"canvas\").getContext('2d', Symbol.hasInstance)", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.invalid.args.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.invalid.args.html
new file mode 100644
index 0000000000..cfa58266ea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.invalid.args.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.invalid.args</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.invalid.args</h1>
+<p class="desc">Calling getContext with invalid arguments.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Calling getContext with invalid arguments.");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.getContext(''), null, "canvas.getContext('')", "null");
+ _assertSame(canvas.getContext('2d#'), null, "canvas.getContext('2d#')", "null");
+ _assertSame(canvas.getContext('This is clearly not a valid context name.'), null, "canvas.getContext('This is clearly not a valid context name.')", "null");
+ _assertSame(canvas.getContext('2d\0'), null, "canvas.getContext('2d\\0')", "null");
+ _assertSame(canvas.getContext('2\uFF44'), null, "canvas.getContext('2\\uFF44')", "null");
+ _assertSame(canvas.getContext('2D'), null, "canvas.getContext('2D')", "null");
+ assert_throws_js(TypeError, function() { canvas.getContext(); });
+ _assertSame(canvas.getContext('null'), null, "canvas.getContext('null')", "null");
+ _assertSame(canvas.getContext('undefined'), null, "canvas.getContext('undefined')", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.prototype.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.prototype.html
new file mode 100644
index 0000000000..5d5edc6864
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.prototype.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.prototype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.prototype</h1>
+<p class="desc">checks CanvasRenderingContext2D prototype</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("checks CanvasRenderingContext2D prototype");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(Object.getPrototypeOf(CanvasRenderingContext2D.prototype), Object.prototype, "Object.getPrototypeOf(CanvasRenderingContext2D.prototype)", "Object.prototype");
+ _assertSame(Object.getPrototypeOf(ctx), CanvasRenderingContext2D.prototype, "Object.getPrototypeOf(ctx)", "CanvasRenderingContext2D.prototype");
+ t.done();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.shared.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.shared.html
new file mode 100644
index 0000000000..fd8deddec0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.shared.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.shared</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.shared</h1>
+<p class="desc">getContext('2d') returns objects which share canvas state</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("getContext('2d') returns objects which share canvas state");
+_addTest(function(canvas, ctx) {
+
+ var ctx2 = canvas.getContext('2d');
+ ctx.fillStyle = '#f00';
+ ctx2.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.exists.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.exists.html
new file mode 100644
index 0000000000..d25f009abb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.exists.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.type.exists</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.type.exists</h1>
+<p class="desc">The 2D context interface is a property of 'window'</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("The 2D context interface is a property of 'window'");
+_addTest(function(canvas, ctx) {
+
+ _assert(window.CanvasRenderingContext2D, "window.CanvasRenderingContext2D");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.extend.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.extend.html
new file mode 100644
index 0000000000..8d34d53101
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.extend.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.type.extend</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.type.extend</h1>
+<p class="desc">Interface methods can be added</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Interface methods can be added");
+_addTest(function(canvas, ctx) {
+
+ window.CanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h)
+ {
+ this.fillStyle = '#0f0';
+ this.fillRect(x, y, w, h);
+ };
+ ctx.fillStyle = '#f00';
+ ctx.fillRectGreen(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.prototype.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.prototype.html
new file mode 100644
index 0000000000..a537fe5106
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.prototype.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.type.prototype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.type.prototype</h1>
+<p class="desc">window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].");
+_addTest(function(canvas, ctx) {
+
+ _assert(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
+ _assert(window.CanvasRenderingContext2D.prototype.fill, "window.CanvasRenderingContext2D.prototype.fill");
+ window.CanvasRenderingContext2D.prototype = null;
+ _assert(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
+ delete window.CanvasRenderingContext2D.prototype;
+ _assert(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
+ window.CanvasRenderingContext2D.prototype.fill = 1;
+ _assertSame(window.CanvasRenderingContext2D.prototype.fill, 1, "window.CanvasRenderingContext2D.prototype.fill", "1");
+ delete window.CanvasRenderingContext2D.prototype.fill;
+ _assertSame(window.CanvasRenderingContext2D.prototype.fill, undefined, "window.CanvasRenderingContext2D.prototype.fill", "undefined");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.replace.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.replace.html
new file mode 100644
index 0000000000..ac3c40587d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.type.replace.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.type.replace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.type.replace</h1>
+<p class="desc">Interface methods can be overridden</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Interface methods can be overridden");
+_addTest(function(canvas, ctx) {
+
+ var fillRect = window.CanvasRenderingContext2D.prototype.fillRect;
+ window.CanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h)
+ {
+ this.fillStyle = '#0f0';
+ fillRect.call(this, x, y, w, h);
+ };
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.unique.html b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.unique.html
new file mode 100644
index 0000000000..c7b1803856
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-context/2d.canvas.context.unique.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.context.unique</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.context.unique</h1>
+<p class="desc">getContext('2d') returns the same object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getContext('2d') returns the same object");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.getContext('2d'), canvas.getContext('2d'), "canvas.getContext('2d')", "canvas.getContext('2d')");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.2dstate.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.2dstate.html
new file mode 100644
index 0000000000..e194001198
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.2dstate.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.initial.reset.2dstate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.initial.reset.2dstate</h1>
+<p class="desc">Resetting the canvas state resets 2D state variables</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state resets 2D state variables");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 100;
+ var default_val;
+
+ default_val = ctx.strokeStyle;
+ ctx.strokeStyle = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.strokeStyle, default_val, "ctx.strokeStyle", "default_val");
+
+ default_val = ctx.fillStyle;
+ ctx.fillStyle = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.fillStyle, default_val, "ctx.fillStyle", "default_val");
+
+ default_val = ctx.globalAlpha;
+ ctx.globalAlpha = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.globalAlpha, default_val, "ctx.globalAlpha", "default_val");
+
+ default_val = ctx.lineWidth;
+ ctx.lineWidth = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.lineWidth, default_val, "ctx.lineWidth", "default_val");
+
+ default_val = ctx.lineCap;
+ ctx.lineCap = "round";
+ canvas.width = 100;
+ _assertSame(ctx.lineCap, default_val, "ctx.lineCap", "default_val");
+
+ default_val = ctx.lineJoin;
+ ctx.lineJoin = "round";
+ canvas.width = 100;
+ _assertSame(ctx.lineJoin, default_val, "ctx.lineJoin", "default_val");
+
+ default_val = ctx.miterLimit;
+ ctx.miterLimit = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.miterLimit, default_val, "ctx.miterLimit", "default_val");
+
+ default_val = ctx.shadowOffsetX;
+ ctx.shadowOffsetX = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowOffsetX, default_val, "ctx.shadowOffsetX", "default_val");
+
+ default_val = ctx.shadowOffsetY;
+ ctx.shadowOffsetY = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowOffsetY, default_val, "ctx.shadowOffsetY", "default_val");
+
+ default_val = ctx.shadowBlur;
+ ctx.shadowBlur = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowBlur, default_val, "ctx.shadowBlur", "default_val");
+
+ default_val = ctx.shadowColor;
+ ctx.shadowColor = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.shadowColor, default_val, "ctx.shadowColor", "default_val");
+
+ default_val = ctx.globalCompositeOperation;
+ ctx.globalCompositeOperation = "copy";
+ canvas.width = 100;
+ _assertSame(ctx.globalCompositeOperation, default_val, "ctx.globalCompositeOperation", "default_val");
+
+ default_val = ctx.font;
+ ctx.font = "25px serif";
+ canvas.width = 100;
+ _assertSame(ctx.font, default_val, "ctx.font", "default_val");
+
+ default_val = ctx.textAlign;
+ ctx.textAlign = "center";
+ canvas.width = 100;
+ _assertSame(ctx.textAlign, default_val, "ctx.textAlign", "default_val");
+
+ default_val = ctx.textBaseline;
+ ctx.textBaseline = "bottom";
+ canvas.width = 100;
+ _assertSame(ctx.textBaseline, default_val, "ctx.textBaseline", "default_val");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.readonly.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.readonly.html
new file mode 100644
index 0000000000..cbbf32f2e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.readonly.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.readonly</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.readonly</h1>
+<p class="desc">CanvasRenderingContext2D.canvas is readonly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("CanvasRenderingContext2D.canvas is readonly");
+_addTest(function(canvas, ctx) {
+
+ var c = document.createElement('canvas');
+ var d = ctx.canvas;
+ _assertDifferent(c, d, "c", "d");
+ ctx.canvas = c;
+ _assertSame(ctx.canvas, d, "ctx.canvas", "d");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.reference.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.reference.html
new file mode 100644
index 0000000000..6a4bdb65b0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.reference.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.reference</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.reference</h1>
+<p class="desc">CanvasRenderingContext2D.canvas refers back to its canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("CanvasRenderingContext2D.canvas refers back to its canvas");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.canvas, canvas, "ctx.canvas", "canvas");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html
new file mode 100644
index 0000000000..acf3f9c7b3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.scaled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.scaled</h1>
+<p class="desc">CSS-scaled canvases get drawn correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="25" style="width: 100px; height: 50px"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.scaled.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("CSS-scaled canvases get drawn correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillStyle = '#0ff';
+ ctx.fillRect(0, 0, 25, 10);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled.png
new file mode 100644
index 0000000000..875407769f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.scaled.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html
new file mode 100644
index 0000000000..0de11e235d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.decimal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.decimal</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100.999" height="100.999"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.decimal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100.999', "canvas.getAttribute('width')", "'100.999'");
+ _assertSame(canvas.getAttribute('height'), '100.999', "canvas.getAttribute('height')", "'100.999'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.decimal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.html
new file mode 100644
index 0000000000..315c8323fa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.em</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.em</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100em" height="100em"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.em.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100em', "canvas.getAttribute('width')", "'100em'");
+ _assertSame(canvas.getAttribute('height'), '100em', "canvas.getAttribute('height')", "'100em'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.em.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.html
new file mode 100644
index 0000000000..b9568712e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.empty</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="" height=""><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.empty.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), '', "canvas.getAttribute('width')", "''");
+ _assertSame(canvas.getAttribute('height'), '', "canvas.getAttribute('height')", "''");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.empty.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.html
new file mode 100644
index 0000000000..208ddeceeb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.exp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.exp</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100e1" height="100e1"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.exp.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100e1', "canvas.getAttribute('width')", "'100e1'");
+ _assertSame(canvas.getAttribute('height'), '100e1', "canvas.getAttribute('height')", "'100e1'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.exp.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.hex.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.hex.html
new file mode 100644
index 0000000000..05f7030d47
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.hex.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.hex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.hex</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0x100" height="0x100"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+ _assertSame(canvas.getAttribute('width'), '0x100', "canvas.getAttribute('width')", "'0x100'");
+ _assertSame(canvas.getAttribute('height'), '0x100', "canvas.getAttribute('height')", "'0x100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.html
new file mode 100644
index 0000000000..3a55fd13dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.junk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.junk</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="#!?" height="#!?"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.junk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), '#!?', "canvas.getAttribute('width')", "'#!?'");
+ _assertSame(canvas.getAttribute('height'), '#!?', "canvas.getAttribute('height')", "'#!?'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.junk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.html
new file mode 100644
index 0000000000..da5f21ad04
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.minus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.minus</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="-100" height="-100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.minus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), '-100', "canvas.getAttribute('width')", "'-100'");
+ _assertSame(canvas.getAttribute('height'), '-100', "canvas.getAttribute('height')", "'-100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.minus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.html
new file mode 100644
index 0000000000..ccc7efaafa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.octal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.octal</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0100" height="0100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.octal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '0100', "canvas.getAttribute('width')", "'0100'");
+ _assertSame(canvas.getAttribute('height'), '0100', "canvas.getAttribute('height')", "'0100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.octal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html
new file mode 100644
index 0000000000..da14fa25c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.onlyspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.onlyspace</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width=" " height=" "><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.onlyspace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), ' ', "canvas.getAttribute('width')", "' '");
+ _assertSame(canvas.getAttribute('height'), ' ', "canvas.getAttribute('height')", "' '");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.html
new file mode 100644
index 0000000000..d699288f73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.percent</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100%" height="100%"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.percent.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100%', "canvas.getAttribute('width')", "'100%'");
+ _assertSame(canvas.getAttribute('height'), '100%', "canvas.getAttribute('height')", "'100%'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.percent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.html
new file mode 100644
index 0000000000..58fb07f179
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.plus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.plus</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="+100" height="+100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.plus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '+100', "canvas.getAttribute('width')", "'+100'");
+ _assertSame(canvas.getAttribute('height'), '+100', "canvas.getAttribute('height')", "'+100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.plus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.html
new file mode 100644
index 0000000000..52fadaad43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.space</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width=" 100" height=" 100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.space.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), ' 100', "canvas.getAttribute('width')", "' 100'");
+ _assertSame(canvas.getAttribute('height'), ' 100', "canvas.getAttribute('height')", "' 100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.space.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html
new file mode 100644
index 0000000000..b18167c599
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.trailingjunk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.trailingjunk</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100#!?" height="100#!?"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.trailingjunk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100#!?', "canvas.getAttribute('width')", "'100#!?'");
+ _assertSame(canvas.getAttribute('height'), '100#!?', "canvas.getAttribute('height')", "'100#!?'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html
new file mode 100644
index 0000000000..79e81c1020
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.whitespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.whitespace</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="&#xD;
+ 100" height="&#xD;
+ 100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.parse.whitespace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '\r\n\t\x0c100', "canvas.getAttribute('width')", "'\\r\\n\\t\\x0c100'");
+ _assertSame(canvas.getAttribute('height'), '\r\n\t\x0c100', "canvas.getAttribute('height')", "'\\r\\n\\t\\x0c100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.zero.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.zero.html
new file mode 100644
index 0000000000..b7fd499d1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.parse.zero.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.parse.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.parse.zero</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0" height="0"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+ _assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
+ _assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.html
new file mode 100644
index 0000000000..b6c2130bf0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.decimal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.decimal</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.decimal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '100.999');
+ canvas.setAttribute('height', '100.999');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100.999', "canvas.getAttribute('width')", "'100.999'");
+ _assertSame(canvas.getAttribute('height'), '100.999', "canvas.getAttribute('height')", "'100.999'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.decimal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.html
new file mode 100644
index 0000000000..f70713fd8f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.em</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.em</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.em.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '100em');
+ canvas.setAttribute('height', '100em');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100em', "canvas.getAttribute('width')", "'100em'");
+ _assertSame(canvas.getAttribute('height'), '100em', "canvas.getAttribute('height')", "'100em'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.em.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.html
new file mode 100644
index 0000000000..fab2394fec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.empty</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.empty.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '');
+ canvas.setAttribute('height', '');
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), '', "canvas.getAttribute('width')", "''");
+ _assertSame(canvas.getAttribute('height'), '', "canvas.getAttribute('height')", "''");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.empty.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.html
new file mode 100644
index 0000000000..cfa11eb302
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.exp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.exp</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.exp.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '100e1');
+ canvas.setAttribute('height', '100e1');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100e1', "canvas.getAttribute('width')", "'100e1'");
+ _assertSame(canvas.getAttribute('height'), '100e1', "canvas.getAttribute('height')", "'100e1'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.exp.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.hex.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.hex.html
new file mode 100644
index 0000000000..80a1fbda60
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.hex.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.hex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.hex</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '0x100');
+ canvas.setAttribute('height', '0x100');
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+ _assertSame(canvas.getAttribute('width'), '0x100', "canvas.getAttribute('width')", "'0x100'");
+ _assertSame(canvas.getAttribute('height'), '0x100', "canvas.getAttribute('height')", "'0x100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.html
new file mode 100644
index 0000000000..b583871f38
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.junk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.junk</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.junk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '#!?');
+ canvas.setAttribute('height', '#!?');
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), '#!?', "canvas.getAttribute('width')", "'#!?'");
+ _assertSame(canvas.getAttribute('height'), '#!?', "canvas.getAttribute('height')", "'#!?'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.junk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.html
new file mode 100644
index 0000000000..90a31403e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.minus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.minus</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.minus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '-100');
+ canvas.setAttribute('height', '-100');
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), '-100', "canvas.getAttribute('width')", "'-100'");
+ _assertSame(canvas.getAttribute('height'), '-100', "canvas.getAttribute('height')", "'-100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.minus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.html
new file mode 100644
index 0000000000..c5b263bd5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.octal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.octal</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.octal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '0100');
+ canvas.setAttribute('height', '0100');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '0100', "canvas.getAttribute('width')", "'0100'");
+ _assertSame(canvas.getAttribute('height'), '0100', "canvas.getAttribute('height')", "'0100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.octal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.html
new file mode 100644
index 0000000000..ac4cdb001b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.onlyspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.onlyspace</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.onlyspace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', ' ');
+ canvas.setAttribute('height', ' ');
+ _assertSame(canvas.width, 300, "canvas.width", "300");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ _assertSame(canvas.getAttribute('width'), ' ', "canvas.getAttribute('width')", "' '");
+ _assertSame(canvas.getAttribute('height'), ' ', "canvas.getAttribute('height')", "' '");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.png
new file mode 100644
index 0000000000..a72d047556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.onlyspace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.html
new file mode 100644
index 0000000000..5aebf5a0b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.percent</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.percent.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '100%');
+ canvas.setAttribute('height', '100%');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100%', "canvas.getAttribute('width')", "'100%'");
+ _assertSame(canvas.getAttribute('height'), '100%', "canvas.getAttribute('height')", "'100%'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.percent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.html
new file mode 100644
index 0000000000..60da44daf3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.plus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.plus</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.plus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '+100');
+ canvas.setAttribute('height', '+100');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '+100', "canvas.getAttribute('width')", "'+100'");
+ _assertSame(canvas.getAttribute('height'), '+100', "canvas.getAttribute('height')", "'+100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.plus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.html
new file mode 100644
index 0000000000..fbfd4c33c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.space</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.space.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', ' 100');
+ canvas.setAttribute('height', ' 100');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), ' 100', "canvas.getAttribute('width')", "' 100'");
+ _assertSame(canvas.getAttribute('height'), ' 100', "canvas.getAttribute('height')", "' 100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.space.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.html
new file mode 100644
index 0000000000..1d230bd654
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.trailingjunk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.trailingjunk</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.trailingjunk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '100#!?');
+ canvas.setAttribute('height', '100#!?');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '100#!?', "canvas.getAttribute('width')", "'100#!?'");
+ _assertSame(canvas.getAttribute('height'), '100#!?', "canvas.getAttribute('height')", "'100#!?'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.trailingjunk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.html
new file mode 100644
index 0000000000..1aa86d6a9e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.whitespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.whitespace</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.size.attributes.setAttribute.whitespace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '\r\n\t\x0c100');
+ canvas.setAttribute('height', '\r\n\t\x0c100');
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+ _assertSame(canvas.getAttribute('width'), '\r\n\t\x0c100', "canvas.getAttribute('width')", "'\\r\\n\\t\\x0c100'");
+ _assertSame(canvas.getAttribute('height'), '\r\n\t\x0c100', "canvas.getAttribute('height')", "'\\r\\n\\t\\x0c100'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.png b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.png
new file mode 100644
index 0000000000..f842673330
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.zero.html b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.zero.html
new file mode 100644
index 0000000000..64b4811d79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.zero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.setAttribute.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.setAttribute.zero</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('width', '0');
+ canvas.setAttribute('height', '0');
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+ _assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
+ _assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.html
new file mode 100644
index 0000000000..cb805b692e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.clear</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.clear.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.clear.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.html
new file mode 100644
index 0000000000..d4e75b7bac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.copy</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,191, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.png
new file mode 100644
index 0000000000..f5e9c21964
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.html
new file mode 100644
index 0000000000..6fded39e44
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.destination-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 128,255,128,191, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.png
new file mode 100644
index 0000000000..504b42756e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.html
new file mode 100644
index 0000000000..7277286d8b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.destination-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,96, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.png
new file mode 100644
index 0000000000..790e418a6b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.html
new file mode 100644
index 0000000000..5860c3d5cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.destination-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.destination-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,32, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.png
new file mode 100644
index 0000000000..7f5ed1a836
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.html
new file mode 100644
index 0000000000..76bad84392
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.destination-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.destination-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 109,255,146,223, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.png
new file mode 100644
index 0000000000..226390b2f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.destination-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.html
new file mode 100644
index 0000000000..8d706df67e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.lighter</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.lighter.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,128,255, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.png
new file mode 100644
index 0000000000..fc33f3301e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.lighter.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.html
new file mode 100644
index 0000000000..cf3e449123
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.source-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.source-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.png
new file mode 100644
index 0000000000..1ef9630195
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.html
new file mode 100644
index 0000000000..dabcced9dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.source-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.png
new file mode 100644
index 0000000000..c26cdccf02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.html
new file mode 100644
index 0000000000..2fcf708796
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.source-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.png
new file mode 100644
index 0000000000..c26cdccf02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.html
new file mode 100644
index 0000000000..b9dca65744
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.source-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.source-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 219,255,36,223, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.png
new file mode 100644
index 0000000000..e63ab7e308
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.source-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.html
new file mode 100644
index 0000000000..c252e17a7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.canvas.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.canvas.xor</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.canvas.xor.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.png
new file mode 100644
index 0000000000..1ef9630195
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.canvas.xor.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.clear.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.clear.html
new file mode 100644
index 0000000000..65cfd951e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.clear.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.clear</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.copy.html
new file mode 100644
index 0000000000..b38397a2c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.copy.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.copy</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-atop.html
new file mode 100644
index 0000000000..79fb3af54c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-atop.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.destination-atop</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-in.html
new file mode 100644
index 0000000000..63e8d3acfd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-in.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.destination-in</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-out.html
new file mode 100644
index 0000000000..839246427f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-out.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.destination-out</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-over.html
new file mode 100644
index 0000000000..fc7f1ab728
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.destination-over.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.destination-over</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.lighter.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.lighter.html
new file mode 100644
index 0000000000..b3acab0231
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.lighter.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.lighter</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-atop.html
new file mode 100644
index 0000000000..49c3eb0bb5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-atop.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.source-atop</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-in.html
new file mode 100644
index 0000000000..afe92ba4bf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-in.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.source-in</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-out.html
new file mode 100644
index 0000000000..43b352fb46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-out.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.source-out</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-over.html
new file mode 100644
index 0000000000..4973f8e6e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.source-over.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.source-over</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.xor.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.xor.html
new file mode 100644
index 0000000000..5239d6fd10
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.clip.xor.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.clip.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.clip.xor</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvas.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvas.html
new file mode 100644
index 0000000000..525a56ebc9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvas.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.canvas</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvascopy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvascopy.html
new file mode 100644
index 0000000000..17a46cfca2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvascopy.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.canvascopy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.canvascopy</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.globalCompositeOperation = 'copy'
+ ctx.globalAlpha = 0.51;
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,130, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvaspattern.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvaspattern.html
new file mode 100644
index 0000000000..eea076c974
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.canvaspattern.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.canvaspattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.canvaspattern</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(canvas2, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.default.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.default.html
new file mode 100644
index 0000000000..97cdf267c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.default.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.globalAlpha, 1.0, "ctx.globalAlpha", "1.0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.fill.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.fill.html
new file mode 100644
index 0000000000..5766fdbe77
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.fill.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.fill</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.fill</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.image.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.image.html
new file mode 100644
index 0000000000..5de1d5ff3e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.image.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.image</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.imagepattern.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.imagepattern.html
new file mode 100644
index 0000000000..87e884524e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.imagepattern.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.imagepattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.imagepattern</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.invalid.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.invalid.html
new file mode 100644
index 0000000000..db67f882f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.invalid.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ ctx.globalAlpha = Infinity;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = -Infinity;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = NaN;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.range.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.range.html
new file mode 100644
index 0000000000..883b0cac69
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.globalAlpha.range.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.globalAlpha.range</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.globalAlpha.range</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = 1.1;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = -0.1;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = 0;
+ _assertSame(ctx.globalAlpha, 0, "ctx.globalAlpha", "0");
+ ctx.globalAlpha = 1;
+ _assertSame(ctx.globalAlpha, 1, "ctx.globalAlpha", "1");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.html
new file mode 100644
index 0000000000..a44f8e35b0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.clear</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.clear.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.clear.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.html
new file mode 100644
index 0000000000..d3c972b6d2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.copy</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,191, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.png
new file mode 100644
index 0000000000..f5e9c21964
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.html
new file mode 100644
index 0000000000..7c6f93448b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.destination-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 128,255,128,191, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.png
new file mode 100644
index 0000000000..504b42756e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.html
new file mode 100644
index 0000000000..a2bf972bb9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.destination-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,96, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.png
new file mode 100644
index 0000000000..790e418a6b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.html
new file mode 100644
index 0000000000..d0d08fa09e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.destination-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.destination-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,32, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.png
new file mode 100644
index 0000000000..7f5ed1a836
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.html
new file mode 100644
index 0000000000..7ac98904f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.destination-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.destination-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 109,255,146,223, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.png
new file mode 100644
index 0000000000..226390b2f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.destination-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.html
new file mode 100644
index 0000000000..1df4c683df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.lighter</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.lighter.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,128,255, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.png
new file mode 100644
index 0000000000..fc33f3301e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.lighter.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.html
new file mode 100644
index 0000000000..86833df6b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.source-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.source-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.png
new file mode 100644
index 0000000000..1ef9630195
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.html
new file mode 100644
index 0000000000..0b6ca4b52e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.source-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.png
new file mode 100644
index 0000000000..c26cdccf02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.html
new file mode 100644
index 0000000000..31dfe471e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.source-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.png
new file mode 100644
index 0000000000..c26cdccf02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.html
new file mode 100644
index 0000000000..e396faa5d7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.source-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.source-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 219,255,36,223, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.png
new file mode 100644
index 0000000000..e63ab7e308
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.source-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.html
new file mode 100644
index 0000000000..d43742c272
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.image.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.image.xor</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.image.xor.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+
+});
+</script>
+<img src="/images/yellow75.png" id="yellow75.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.png
new file mode 100644
index 0000000000..1ef9630195
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.image.xor.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.casesensitive.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.casesensitive.html
new file mode 100644
index 0000000000..13ae99b35f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.casesensitive.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.casesensitive</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.casesensitive</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'Source-over';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.clear.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.clear.html
new file mode 100644
index 0000000000..c1e88b4894
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.clear.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.clear</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'clear';
+ _assertSame(ctx.globalCompositeOperation, 'clear', "ctx.globalCompositeOperation", "'clear'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.darker.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.darker.html
new file mode 100644
index 0000000000..4fb6998f71
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.darker.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.darker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.darker</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'darker';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.default.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.default.html
new file mode 100644
index 0000000000..5ccd488b3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.default.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.globalCompositeOperation, 'source-over', "ctx.globalCompositeOperation", "'source-over'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.get.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.get.html
new file mode 100644
index 0000000000..27b89c9fed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.get.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.get</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.get</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
+ 'destination-atop', 'destination-in', 'destination-out', 'destination-over',
+ 'lighter', 'copy', 'xor'];
+ for (var i = 0; i < modes.length; ++i)
+ {
+ ctx.globalCompositeOperation = modes[i];
+ _assertSame(ctx.globalCompositeOperation, modes[i], "ctx.globalCompositeOperation", "modes[\""+(i)+"\"]");
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.highlight.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.highlight.html
new file mode 100644
index 0000000000..45c5dd15eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.highlight.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.highlight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.highlight</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'highlight';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.nullsuffix.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.nullsuffix.html
new file mode 100644
index 0000000000..8a2443ff41
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.nullsuffix.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.nullsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.nullsuffix</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'source-over\0';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.over.html
new file mode 100644
index 0000000000..1d742ef3cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.over.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'over';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.unrecognised.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.unrecognised.html
new file mode 100644
index 0000000000..e4aa877d96
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.operation.unrecognised.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.operation.unrecognised</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.operation.unrecognised</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'nonexistent';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.html
new file mode 100644
index 0000000000..a946989544
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.clear</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.clear.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.clear.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.html
new file mode 100644
index 0000000000..14bee74452
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.copy</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.png
new file mode 100644
index 0000000000..fc0883e74f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.html
new file mode 100644
index 0000000000..d82fb44cce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.destination-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.png
new file mode 100644
index 0000000000..dd04072baf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.html
new file mode 100644
index 0000000000..6a491f57c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.destination-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.png
new file mode 100644
index 0000000000..dd04072baf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.html
new file mode 100644
index 0000000000..bcc7f24e7a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.destination-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.destination-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.html
new file mode 100644
index 0000000000..6e634e6ae5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.destination-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.destination-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.png
new file mode 100644
index 0000000000..dd04072baf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.destination-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.html
new file mode 100644
index 0000000000..fddbe92420
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.lighter</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.lighter.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,255,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.png
new file mode 100644
index 0000000000..bf48767a88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.lighter.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.html
new file mode 100644
index 0000000000..4bb0e3d8b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.source-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.source-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.png
new file mode 100644
index 0000000000..fc0883e74f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.html
new file mode 100644
index 0000000000..f8fee40a93
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.source-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.png
new file mode 100644
index 0000000000..fc0883e74f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.html
new file mode 100644
index 0000000000..2c9d086182
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.source-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.html
new file mode 100644
index 0000000000..335987b12b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.source-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.source-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.png
new file mode 100644
index 0000000000..fc0883e74f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.source-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.html
new file mode 100644
index 0000000000..d9da43070e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.solid.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.solid.xor</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.solid.xor.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.solid.xor.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.html
new file mode 100644
index 0000000000..de417eea34
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.clear</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.clear.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.clear.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.html
new file mode 100644
index 0000000000..2048975ec3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.copy</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,191, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.png
new file mode 100644
index 0000000000..b0cbe3a552
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.html
new file mode 100644
index 0000000000..1da1f1a4ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.destination-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,128,128,191, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.png
new file mode 100644
index 0000000000..5db0a0484a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.html
new file mode 100644
index 0000000000..b0f8abe0ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.destination-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,96, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.png
new file mode 100644
index 0000000000..c6895de985
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.html
new file mode 100644
index 0000000000..badbfc4ad7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.destination-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.destination-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,32, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.png
new file mode 100644
index 0000000000..873a9c45d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.html
new file mode 100644
index 0000000000..e8e0051b2c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.destination-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.destination-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,146,109,223, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.png
new file mode 100644
index 0000000000..5a8726bbca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.destination-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.html
new file mode 100644
index 0000000000..6e4c42ab9a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.lighter</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.lighter.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,128,191,255, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.png
new file mode 100644
index 0000000000..0e1c28c0cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.lighter.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.html
new file mode 100644
index 0000000000..d3d3fbda12
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.source-atop</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.source-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,64,191,128, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.png
new file mode 100644
index 0000000000..e0afff6b00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.html
new file mode 100644
index 0000000000..27c66cb673
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.source-in</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,96, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.png
new file mode 100644
index 0000000000..1459b5e54e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.html
new file mode 100644
index 0000000000..31bb6a2403
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.source-out</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,96, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.png
new file mode 100644
index 0000000000..1459b5e54e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.html
new file mode 100644
index 0000000000..ee20f52b46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.source-over</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.source-over.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,36,219,223, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.png
new file mode 100644
index 0000000000..02acb7a861
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.source-over.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.html
new file mode 100644
index 0000000000..d1818750df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.transparent.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.transparent.xor</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.transparent.xor.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,64,191,128, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.png
new file mode 100644
index 0000000000..e0afff6b00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.transparent.xor.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.html
new file mode 100644
index 0000000000..9dfd650b98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.fill.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.fill.copy</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.fill.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.html
new file mode 100644
index 0000000000..685a139504
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.fill.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.fill.destination-atop</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.fill.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.html
new file mode 100644
index 0000000000..9ca8021151
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.fill.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.fill.destination-in</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.fill.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.html
new file mode 100644
index 0000000000..9f1a5f9d51
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.fill.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.fill.source-in</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.fill.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.html
new file mode 100644
index 0000000000..7653677fd5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.fill.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.fill.source-out</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.fill.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.fill.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.html
new file mode 100644
index 0000000000..61dd0381ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.image.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.image.copy</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.image.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.drawImage(document.getElementById('yellow.png'), 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.html
new file mode 100644
index 0000000000..440c832c71
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.image.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.image.destination-atop</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.image.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.drawImage(document.getElementById('yellow.png'), 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.html
new file mode 100644
index 0000000000..03e2e807ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.image.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.image.destination-in</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.image.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.drawImage(document.getElementById('yellow.png'), 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.html
new file mode 100644
index 0000000000..de2e5fad63
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.image.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.image.source-in</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.image.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.drawImage(document.getElementById('yellow.png'), 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.html
new file mode 100644
index 0000000000..5cb9b072b9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.image.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.image.source-out</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.image.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.drawImage(document.getElementById('yellow.png'), 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.image.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.html
new file mode 100644
index 0000000000..cac66ade5a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.nocontext.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.nocontext.copy</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.nocontext.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var canvas2 = document.createElement('canvas');
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.html
new file mode 100644
index 0000000000..c7cecc2e3d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.nocontext.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.nocontext.destination-atop</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.nocontext.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var canvas2 = document.createElement('canvas');
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.html
new file mode 100644
index 0000000000..e090d7d4b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.nocontext.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.nocontext.destination-in</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.nocontext.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var canvas2 = document.createElement('canvas');
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.html
new file mode 100644
index 0000000000..0436b40817
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.nocontext.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.nocontext.source-in</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.nocontext.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var canvas2 = document.createElement('canvas');
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.html
new file mode 100644
index 0000000000..efbc8ab2f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.nocontext.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.nocontext.source-out</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.nocontext.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var canvas2 = document.createElement('canvas');
+ ctx.drawImage(canvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.nocontext.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.html
new file mode 100644
index 0000000000..aaee92022a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.pattern.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.pattern.copy</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.pattern.copy.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = ctx.createPattern(document.getElementById('yellow.png'), 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.copy.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.html
new file mode 100644
index 0000000000..aded018f8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.pattern.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.pattern.destination-atop</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.pattern.destination-atop.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = ctx.createPattern(document.getElementById('yellow.png'), 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-atop.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.html
new file mode 100644
index 0000000000..e520e1ffa3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.pattern.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.pattern.destination-in</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.pattern.destination-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = ctx.createPattern(document.getElementById('yellow.png'), 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.destination-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.html
new file mode 100644
index 0000000000..bee654877b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.pattern.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.pattern.source-in</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.pattern.source-in.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = ctx.createPattern(document.getElementById('yellow.png'), 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-in.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.html b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.html
new file mode 100644
index 0000000000..947893091e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.composite.uncovered.pattern.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.composite.uncovered.pattern.source-out</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.composite.uncovered.pattern.source-out.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = ctx.createPattern(document.getElementById('yellow.png'), 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.png b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/compositing/2d.composite.uncovered.pattern.source-out.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.basics.html b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.basics.html
new file mode 100644
index 0000000000..cea531f9db
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.basics.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.basics</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.basics</h1>
+<p class="desc">void methods return undefined</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("void methods return undefined");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.save(), undefined, "ctx.save()", "undefined");
+ _assertSame(ctx.restore(), undefined, "ctx.restore()", "undefined");
+ _assertSame(ctx.scale(1, 1), undefined, "ctx.scale(1, 1)", "undefined");
+ _assertSame(ctx.rotate(0), undefined, "ctx.rotate(0)", "undefined");
+ _assertSame(ctx.translate(0, 0), undefined, "ctx.translate(0, 0)", "undefined");
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ _assertSame(ctx.transform(1, 0, 0, 1, 0, 0), undefined, "ctx.transform(1, 0, 0, 1, 0, 0)", "undefined");
+ }
+ if (ctx.setTransform) {
+ _assertSame(ctx.setTransform(1, 0, 0, 1, 0, 0), undefined, "ctx.setTransform(1, 0, 0, 1, 0, 0)", "undefined");
+ _assertSame(ctx.setTransform(), undefined, "ctx.setTransform()", "undefined");
+ }
+ _assertSame(ctx.clearRect(0, 0, 0, 0), undefined, "ctx.clearRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.fillRect(0, 0, 0, 0), undefined, "ctx.fillRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.strokeRect(0, 0, 0, 0), undefined, "ctx.strokeRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.beginPath(), undefined, "ctx.beginPath()", "undefined");
+ _assertSame(ctx.closePath(), undefined, "ctx.closePath()", "undefined");
+ _assertSame(ctx.moveTo(0, 0), undefined, "ctx.moveTo(0, 0)", "undefined");
+ _assertSame(ctx.lineTo(0, 0), undefined, "ctx.lineTo(0, 0)", "undefined");
+ _assertSame(ctx.quadraticCurveTo(0, 0, 0, 0), undefined, "ctx.quadraticCurveTo(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.bezierCurveTo(0, 0, 0, 0, 0, 0), undefined, "ctx.bezierCurveTo(0, 0, 0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.arcTo(0, 0, 0, 0, 1), undefined, "ctx.arcTo(0, 0, 0, 0, 1)", "undefined");
+ _assertSame(ctx.rect(0, 0, 0, 0), undefined, "ctx.rect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.arc(0, 0, 1, 0, 0, true), undefined, "ctx.arc(0, 0, 1, 0, 0, true)", "undefined");
+ _assertSame(ctx.fill(), undefined, "ctx.fill()", "undefined");
+ _assertSame(ctx.stroke(), undefined, "ctx.stroke()", "undefined");
+ _assertSame(ctx.clip(), undefined, "ctx.clip()", "undefined");
+ if (ctx.fillText) {
+ _assertSame(ctx.fillText('test', 0, 0), undefined, "ctx.fillText('test', 0, 0)", "undefined");
+ _assertSame(ctx.strokeText('test', 0, 0), undefined, "ctx.strokeText('test', 0, 0)", "undefined");
+ }
+ if (ctx.putImageData) {
+ _assertSame(ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0), undefined, "ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0)", "undefined");
+ }
+ _assertSame(ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white'), undefined, "ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white')", "undefined");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.delete.html b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.delete.html
new file mode 100644
index 0000000000..a33cc869d6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.delete.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.delete</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.delete</h1>
+<p class="desc">window.CanvasRenderingContext2D is Configurable</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("window.CanvasRenderingContext2D is Configurable");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.CanvasRenderingContext2D, undefined, "window.CanvasRenderingContext2D", "undefined");
+ _assertSame(delete window.CanvasRenderingContext2D, true, "delete window.CanvasRenderingContext2D", "true");
+ _assertSame(window.CanvasRenderingContext2D, undefined, "window.CanvasRenderingContext2D", "undefined");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.drawings.html b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.drawings.html
new file mode 100644
index 0000000000..efdad2eab9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.drawings.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.drawings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.drawings</h1>
+<p class="desc">void methods return undefined</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("void methods return undefined");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.missingargs.html b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.missingargs.html
new file mode 100644
index 0000000000..6744c6c381
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/conformance-requirements/2d.conformance.requirements.missingargs.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.conformance.requirements.missingargs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.conformance.requirements.missingargs</h1>
+<p class="desc">Missing arguments cause TypeError</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Missing arguments cause TypeError");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.scale(); });
+ assert_throws_js(TypeError, function() { ctx.scale(1); });
+ assert_throws_js(TypeError, function() { ctx.rotate(); });
+ assert_throws_js(TypeError, function() { ctx.translate(); });
+ assert_throws_js(TypeError, function() { ctx.translate(0); });
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ assert_throws_js(TypeError, function() { ctx.transform(); });
+ assert_throws_js(TypeError, function() { ctx.transform(1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1, 0); });
+ }
+ if (ctx.setTransform) {
+ assert_throws_js(TypeError, function() { ctx.setTransform(1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1, 0); });
+ }
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createPattern(canvas); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.moveTo(); });
+ assert_throws_js(TypeError, function() { ctx.moveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.lineTo(); });
+ assert_throws_js(TypeError, function() { ctx.lineTo(0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.rect(); });
+ assert_throws_js(TypeError, function() { ctx.rect(0); });
+ assert_throws_js(TypeError, function() { ctx.rect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.rect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arc(); });
+ assert_throws_js(TypeError, function() { ctx.arc(0); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1, 0); });
+ // (6th argument to arc is optional)
+ if (ctx.isPointInPath) {
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(0); });
+ }
+ if (ctx.drawFocusRing) {
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas, 0); });
+ }
+ if (ctx.fillText) {
+ assert_throws_js(TypeError, function() { ctx.fillText(); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test'); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeText(); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test'); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.measureText(); });
+ }
+ assert_throws_js(TypeError, function() { ctx.drawImage(); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(canvas, 0); });
+ // TODO: n >= 3 args on drawImage could be either a valid overload,
+ // or too few for another overload, or too many for another
+ // overload - what should happen?
+ if (ctx.createImageData) {
+ assert_throws_js(TypeError, function() { ctx.createImageData(); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(1); });
+ }
+ if (ctx.getImageData) {
+ assert_throws_js(TypeError, function() { ctx.getImageData(); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0, 1); });
+ }
+ if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ assert_throws_js(TypeError, function() { ctx.putImageData(); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0); });
+ }
+ var g = ctx.createLinearGradient(0, 0, 0, 0);
+ assert_throws_js(TypeError, function() { g.addColorStop(); });
+ assert_throws_js(TypeError, function() { g.addColorStop(0); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.3arg.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.3arg.html
new file mode 100644
index 0000000000..d9e2de563b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.3arg.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.3arg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.3arg</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0);
+ ctx.drawImage(bitmap_red, -100, 0);
+ ctx.drawImage(bitmap_red, 100, 0);
+ ctx.drawImage(bitmap_red, 0, -50);
+ ctx.drawImage(bitmap_red, 0, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.5arg.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.5arg.html
new file mode 100644
index 0000000000..befa7108f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.5arg.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.5arg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.5arg</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html
new file mode 100644
index 0000000000..f71eebc2e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.9arg.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.9arg.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html
new file mode 100644
index 0000000000..98da8eccbd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.9arg.destpos</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.9arg.destpos</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, -100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -50, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html
new file mode 100644
index 0000000000..f21096cd96
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.9arg.destsize</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.9arg.destsize</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 1, 1, 1, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, -50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -25, 100, 25);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 25);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html
new file mode 100644
index 0000000000..ca4cc18948
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.9arg.sourcepos</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.9arg.sourcepos</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 140, 20, 100, 50, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html
new file mode 100644
index 0000000000..fb38943cfa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.9arg.sourcesize</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.9arg.sourcesize</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 0, 256, 256, 0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 51, 26);
+ ctx.fillRect(49, 24, 51, 26);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 20,20, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,20, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 20,30, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,30, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.alpha.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.alpha.html
new file mode 100644
index 0000000000..52acd11803
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.alpha.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.alpha</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.animated.gif.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.animated.gif.html
new file mode 100644
index 0000000000..6330d06ade
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.animated.gif.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.animated.gif</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.animated.gif</h1>
+<p class="desc">drawImage() of an animated GIF draws the first frame</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage() of an animated GIF draws the first frame");
+_addTest(function(canvas, ctx) {
+
+ deferTest();
+ step_timeout(t.step_func_done(function () {
+ ctx.drawImage(document.getElementById('anim-gr.gif'), 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ }), 500);
+
+});
+</script>
+<img src="/images/anim-gr.gif" id="anim-gr.gif" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.broken.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.broken.html
new file mode 100644
index 0000000000..f6516a8ecc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.broken.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.broken</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.broken</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ const response = await fetch('/images/broken.png');
+ const blob = await response.blob();
+
+ await promise_rejects_dom(t, 'InvalidStateError', createImageBitmap(blob), 'The source image could not be decoded.');
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.canvas.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.canvas.html
new file mode 100644
index 0000000000..d1f9aeb326
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.canvas.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.canvas</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(canvas2, 0, 0);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+ ctx.drawImage(document.createElement('canvas'), 0, 0);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.clip.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.clip.html
new file mode 100644
index 0000000000..70ec029d8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.clip.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.clip</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.composite.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.composite.html
new file mode 100644
index 0000000000..4ff2026aad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.composite.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.composite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.composite</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.floatsource.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.floatsource.html
new file mode 100644
index 0000000000..3e100c257f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.floatsource.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.floatsource</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.floatsource</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.emptysrc.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.emptysrc.html
new file mode 100644
index 0000000000..849f41aaf6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.emptysrc.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.incomplete.emptysrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.incomplete.emptysrc</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('red.png');
+ img.src = "";
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.immediate.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.immediate.html
new file mode 100644
index 0000000000..d2e8108d90
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.immediate.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.incomplete.immediate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.incomplete.immediate</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = new Image();
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.nosrc.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.nosrc.html
new file mode 100644
index 0000000000..dccf75c6d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.nosrc.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.incomplete.nosrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.incomplete.nosrc</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = new Image();
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.reload.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.reload.html
new file mode 100644
index 0000000000..b4a8440e46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.reload.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.incomplete.reload</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.incomplete.reload</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('yellow.png');
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm,
+ // and resets the image to the "unavailable" state.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.removedsrc.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.removedsrc.html
new file mode 100644
index 0000000000..91e11eb15c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.incomplete.removedsrc.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.incomplete.removedsrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.incomplete.removedsrc</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('red.png');
+ img.removeAttribute('src');
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedest.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedest.html
new file mode 100644
index 0000000000..94d4f71a7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedest.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.negativedest</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.negativedest</h1>
+<p class="desc">Negative destination width/height represents the correct rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, 50, 50, 0, 50, 50, -50);
+ ctx.drawImage(bitmap, 100, 128, 50, -50, 100, 50, -50, -50);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Negative destination width/height represents the correct rectangle");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedir.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedir.html
new file mode 100644
index 0000000000..281da9a573
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativedir.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.negativedir</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.negativedir</h1>
+<p class="desc">Negative dimensions do not affect the direction of the image</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 178, 50, -100, 0, 0, 50, 100);
+ ctx.drawImage(bitmap, 0, 78, 50, 100, 50, 100, 50, -100);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Negative dimensions do not affect the direction of the image");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativesource.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativesource.html
new file mode 100644
index 0000000000..5a504973d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.negativesource.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.negativesource</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.negativesource</h1>
+<p class="desc">Negative source width/height represents the correct rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, -100, 50, 0, 0, 50, 50);
+ ctx.drawImage(bitmap, 100, 128, -100, -50, 50, 0, 50, 50);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Negative source width/height represents the correct rectangle");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonexistent.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonexistent.html
new file mode 100644
index 0000000000..0cebf6cf68
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonexistent.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.nonexistent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.nonexistent</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('not-found-at-all.png');
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(img, 0, 0); });
+
+});
+</script>
+<img src="/images/not-found-at-all.png" id="not-found-at-all.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html
new file mode 100644
index 0000000000..8225d15fdd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html
@@ -0,0 +1,335 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.nonfinite</h1>
+<p class="desc">drawImage() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, Infinity, 0);
+ ctx.drawImage(bitmap, -Infinity, 0);
+ ctx.drawImage(bitmap, NaN, 0);
+ ctx.drawImage(bitmap, 0, Infinity);
+ ctx.drawImage(bitmap, 0, -Infinity);
+ ctx.drawImage(bitmap, 0, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, -Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, NaN, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, -Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, NaN, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, -Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, NaN, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, -Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, -Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, NaN, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, -Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, NaN, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, -Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, NaN, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, -Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, NaN, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, -Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, NaN, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, -Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, NaN, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, -Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, NaN, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, -Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+}, "drawImage() with Infinity/NaN is ignored");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nowrap.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nowrap.html
new file mode 100644
index 0000000000..8c32461b3a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.nowrap.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.nowrap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.nowrap</h1>
+<p class="desc">Stretched images do not get pixels wrapping around the edges</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, -1950, 0, 2000, 50);
+ _assertPixelApprox(canvas, 45,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 55,25, 0,255,0,255, 2);
+
+}, "Stretched images do not get pixels wrapping around the edges");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.null.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.null.html
new file mode 100644
index 0000000000..0f46c97dce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.null.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.null</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.drawImage(null, 0, 0); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.path.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.path.html
new file mode 100644
index 0000000000..52852ec32e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.path.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.path</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ ctx.fill();
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.1.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.1.html
new file mode 100644
index 0000000000..90eaaea5d9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.self.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.self.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.drawImage(canvas, 50, 0);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.2.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.2.html
new file mode 100644
index 0000000000..39e619ddc5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.self.2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.self.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.self.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 1, 100, 49);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 1);
+ ctx.drawImage(canvas, 0, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 2);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.svg.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.svg.html
new file mode 100644
index 0000000000..bcfcdadb28
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.svg.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.svg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.svg</h1>
+<p class="desc">drawImage() of an SVG image</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ const img = new Image();
+ const imageLoadPromise = new Promise((resolve, reject) => {
+ img.onload = () => resolve();
+ img.onerror = (err) => reject(err);
+ });
+ img.src = '/images/green.svg';
+ await imageLoadPromise;
+
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50, 25, 0, 255, 0, 255, 2);
+
+}, "drawImage() of an SVG image");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.transform.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.transform.html
new file mode 100644
index 0000000000..42a277e200
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.transform.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.transform</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(100, 0);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
new file mode 100644
index 0000000000..73e8f45090
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.wrongtype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.wrongtype</h1>
+<p class="desc">Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.drawImage(undefined, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.drawImage("", 0, 0); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.paragraph.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.paragraph.html
new file mode 100644
index 0000000000..ef0be39ca7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.wrongtype.paragraph.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.wrongtype.paragraph</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.wrongtype.paragraph</h1>
+<p class="desc">Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.drawImage(document.createElement('p'), 0, 0); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html
new file mode 100644
index 0000000000..d3c644cf88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.zerocanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.zerocanvas</h1>
+<p class="desc">drawImage with zero-sized canvas as the source shoud throw exception</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage with zero-sized canvas as the source shoud throw exception");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 0;
+ canvas2.height = 50;
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(canvas2, 0, 0); });
+
+ canvas2.width = 50;
+ canvas2.height = 0;
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(canvas2, 0, 0); });
+
+ canvas2.width = 0;
+ canvas2.height = 0;
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(canvas2, 0, 0); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.html
new file mode 100644
index 0000000000..2b7b4ebea6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.zerosource</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.zerosource</h1>
+<p class="desc">drawImage with zero-sized source rectangle draws nothing without exception</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10, 10, 0, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 1, 0, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 0, 0, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "drawImage with zero-sized source rectangle draws nothing without exception");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html
new file mode 100644
index 0000000000..ea00f1f9a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.drawImage.zerosource.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.drawImage.zerosource.image</h1>
+<p class="desc">drawImage with zero-sized source rectangle from image draws nothing without exception</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ function loadImage(src) {
+ return new Promise((resolve, reject) => {
+ const img = new Image();
+ img.onload = () => resolve(img);
+ img.onerror = (err) => reject(err);
+ img.src = src;
+ });
+ }
+ const img1 = await loadImage('/images/red-zerowidth.svg');
+ const img2 = await loadImage('/images/red-zeroheight.svg');
+ const img3 = await loadImage('/images/red-zerosize.svg');
+
+ ctx.drawImage(img1, 0, 0, 100, 50);
+ ctx.drawImage(img2, 0, 0, 100, 50);
+ ctx.drawImage(img3, 0, 0, 100, 50);
+ _assertPixel(canvas, 50, 25, 0, 255, 0, 255);
+
+}, "drawImage with zero-sized source rectangle from image draws nothing without exception");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html
new file mode 100644
index 0000000000..78a8c3ac06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.basic</h1>
+<p class="desc">clearRect clears to transparent black</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect clears to transparent black");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html
new file mode 100644
index 0000000000..eb43a401e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.clip</h1>
+<p class="desc">clearRect is affected by clipping regions</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect is affected by clipping regions");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html
new file mode 100644
index 0000000000..73b87ecc81
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.globalalpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.globalalpha</h1>
+<p class="desc">clearRect is not affected by globalAlpha</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect is not affected by globalAlpha");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.1;
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html
new file mode 100644
index 0000000000..9eb3d33834
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.globalcomposite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.globalcomposite</h1>
+<p class="desc">clearRect is not affected by globalCompositeOperation</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect is not affected by globalCompositeOperation");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html
new file mode 100644
index 0000000000..baa48e2ba3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.negative</h1>
+<p class="desc">clearRect of negative sizes works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect of negative sizes works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 50, 25);
+ ctx.clearRect(100, 0, -50, 25);
+ ctx.clearRect(0, 50, 50, -25);
+ ctx.clearRect(100, 50, -50, -25);
+ _assertPixel(canvas, 25,12, 0,0,0,0);
+ _assertPixel(canvas, 75,12, 0,0,0,0);
+ _assertPixel(canvas, 25,37, 0,0,0,0);
+ _assertPixel(canvas, 75,37, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html
new file mode 100644
index 0000000000..726ed05772
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.nonfinite</h1>
+<p class="desc">clearRect() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(Infinity, 0, 100, 50);
+ ctx.clearRect(-Infinity, 0, 100, 50);
+ ctx.clearRect(NaN, 0, 100, 50);
+ ctx.clearRect(0, Infinity, 100, 50);
+ ctx.clearRect(0, -Infinity, 100, 50);
+ ctx.clearRect(0, NaN, 100, 50);
+ ctx.clearRect(0, 0, Infinity, 50);
+ ctx.clearRect(0, 0, -Infinity, 50);
+ ctx.clearRect(0, 0, NaN, 50);
+ ctx.clearRect(0, 0, 100, Infinity);
+ ctx.clearRect(0, 0, 100, -Infinity);
+ ctx.clearRect(0, 0, 100, NaN);
+ ctx.clearRect(Infinity, Infinity, 100, 50);
+ ctx.clearRect(Infinity, Infinity, Infinity, 50);
+ ctx.clearRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.clearRect(Infinity, Infinity, 100, Infinity);
+ ctx.clearRect(Infinity, 0, Infinity, 50);
+ ctx.clearRect(Infinity, 0, Infinity, Infinity);
+ ctx.clearRect(Infinity, 0, 100, Infinity);
+ ctx.clearRect(0, Infinity, Infinity, 50);
+ ctx.clearRect(0, Infinity, Infinity, Infinity);
+ ctx.clearRect(0, Infinity, 100, Infinity);
+ ctx.clearRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.path.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.path.html
new file mode 100644
index 0000000000..77c9c037b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.path.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.path</h1>
+<p class="desc">clearRect does not affect the current path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect does not affect the current path");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 16, 16);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html
new file mode 100644
index 0000000000..8240073a28
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.shadow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.shadow</h1>
+<p class="desc">clearRect does not draw shadows</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect does not draw shadows");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.clearRect(0, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html
new file mode 100644
index 0000000000..347bedb835
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.transform</h1>
+<p class="desc">clearRect is affected by transforms</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect is affected by transforms");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.clearRect(0, -5, 10, 5);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html
new file mode 100644
index 0000000000..2c192a7102
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.clearRect.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.clearRect.zero</h1>
+<p class="desc">clearRect of zero pixels has no effect</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("clearRect of zero pixels has no effect");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 0);
+ ctx.clearRect(0, 0, 0, 50);
+ ctx.clearRect(0, 0, 0, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html
new file mode 100644
index 0000000000..f29daf426a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.basic</h1>
+<p class="desc">fillRect works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html
new file mode 100644
index 0000000000..cc46b765d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.clip</h1>
+<p class="desc">fillRect is affected by clipping regions</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect is affected by clipping regions");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html
new file mode 100644
index 0000000000..7c64952e8b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.negative</h1>
+<p class="desc">fillRect of negative sizes works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect of negative sizes works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillRect(100, 0, -50, 25);
+ ctx.fillRect(0, 50, 50, -25);
+ ctx.fillRect(100, 50, -50, -25);
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html
new file mode 100644
index 0000000000..090607766d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.nonfinite</h1>
+<p class="desc">fillRect() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(Infinity, 0, 100, 50);
+ ctx.fillRect(-Infinity, 0, 100, 50);
+ ctx.fillRect(NaN, 0, 100, 50);
+ ctx.fillRect(0, Infinity, 100, 50);
+ ctx.fillRect(0, -Infinity, 100, 50);
+ ctx.fillRect(0, NaN, 100, 50);
+ ctx.fillRect(0, 0, Infinity, 50);
+ ctx.fillRect(0, 0, -Infinity, 50);
+ ctx.fillRect(0, 0, NaN, 50);
+ ctx.fillRect(0, 0, 100, Infinity);
+ ctx.fillRect(0, 0, 100, -Infinity);
+ ctx.fillRect(0, 0, 100, NaN);
+ ctx.fillRect(Infinity, Infinity, 100, 50);
+ ctx.fillRect(Infinity, Infinity, Infinity, 50);
+ ctx.fillRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.fillRect(Infinity, Infinity, 100, Infinity);
+ ctx.fillRect(Infinity, 0, Infinity, 50);
+ ctx.fillRect(Infinity, 0, Infinity, Infinity);
+ ctx.fillRect(Infinity, 0, 100, Infinity);
+ ctx.fillRect(0, Infinity, Infinity, 50);
+ ctx.fillRect(0, Infinity, Infinity, Infinity);
+ ctx.fillRect(0, Infinity, 100, Infinity);
+ ctx.fillRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.path.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.path.html
new file mode 100644
index 0000000000..39a6e18103
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.path.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.path</h1>
+<p class="desc">fillRect does not affect the current path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect does not affect the current path");
+_addTest(function(canvas, ctx) {
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html
new file mode 100644
index 0000000000..48aa8538f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.shadow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.shadow</h1>
+<p class="desc">fillRect draws shadows</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect draws shadows");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html
new file mode 100644
index 0000000000..de6f790bc7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.transform</h1>
+<p class="desc">fillRect is affected by transforms</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect is affected by transforms");
+_addTest(function(canvas, ctx) {
+
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -5, 10, 5);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html
new file mode 100644
index 0000000000..095eb19a66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillRect.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillRect.zero</h1>
+<p class="desc">fillRect of zero pixels has no effect</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect of zero pixels has no effect");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 0);
+ ctx.fillRect(0, 0, 0, 50);
+ ctx.fillRect(0, 0, 0, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html
new file mode 100644
index 0000000000..d2ea813178
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.basic</h1>
+<p class="desc">strokeRect works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect works");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html
new file mode 100644
index 0000000000..31db69b6cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.clip</h1>
+<p class="desc">strokeRect is affected by clipping regions</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect is affected by clipping regions");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html
new file mode 100644
index 0000000000..323b663145
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.globalalpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.globalalpha</h1>
+<p class="desc">strokeRect is affected by globalAlpha</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect is affected by globalAlpha");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalAlpha = 0;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html
new file mode 100644
index 0000000000..671db7f07a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.globalcomposite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.globalcomposite</h1>
+<p class="desc">strokeRect is not affected by globalCompositeOperation</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect is not affected by globalCompositeOperation");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html
new file mode 100644
index 0000000000..20bbc5bafe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.negative</h1>
+<p class="desc">strokeRect of negative sizes works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect of negative sizes works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 25;
+ ctx.strokeRect(12, 12, 26, 1);
+ ctx.strokeRect(88, 12, -26, 1);
+ ctx.strokeRect(12, 38, 26, -1);
+ ctx.strokeRect(88, 38, -26, -1);
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html
new file mode 100644
index 0000000000..af7a393c8f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.nonfinite</h1>
+<p class="desc">strokeRect() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 150;
+ ctx.strokeRect(Infinity, 0, 100, 50);
+ ctx.strokeRect(-Infinity, 0, 100, 50);
+ ctx.strokeRect(NaN, 0, 100, 50);
+ ctx.strokeRect(0, Infinity, 100, 50);
+ ctx.strokeRect(0, -Infinity, 100, 50);
+ ctx.strokeRect(0, NaN, 100, 50);
+ ctx.strokeRect(0, 0, Infinity, 50);
+ ctx.strokeRect(0, 0, -Infinity, 50);
+ ctx.strokeRect(0, 0, NaN, 50);
+ ctx.strokeRect(0, 0, 100, Infinity);
+ ctx.strokeRect(0, 0, 100, -Infinity);
+ ctx.strokeRect(0, 0, 100, NaN);
+ ctx.strokeRect(Infinity, Infinity, 100, 50);
+ ctx.strokeRect(Infinity, Infinity, Infinity, 50);
+ ctx.strokeRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.strokeRect(Infinity, Infinity, 100, Infinity);
+ ctx.strokeRect(Infinity, 0, Infinity, 50);
+ ctx.strokeRect(Infinity, 0, Infinity, Infinity);
+ ctx.strokeRect(Infinity, 0, 100, Infinity);
+ ctx.strokeRect(0, Infinity, Infinity, 50);
+ ctx.strokeRect(0, Infinity, Infinity, Infinity);
+ ctx.strokeRect(0, Infinity, 100, Infinity);
+ ctx.strokeRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html
new file mode 100644
index 0000000000..121789d864
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.path</h1>
+<p class="desc">strokeRect does not affect the current path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect does not affect the current path");
+_addTest(function(canvas, ctx) {
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html
new file mode 100644
index 0000000000..8e7a50a745
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.shadow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.shadow</h1>
+<p class="desc">strokeRect draws shadows</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect draws shadows");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, -75, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html
new file mode 100644
index 0000000000..312b9d2003
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.transform</h1>
+<p class="desc">fillRect is affected by transforms</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillRect is affected by transforms");
+_addTest(function(canvas, ctx) {
+
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(2.5, -2.6, 5, 0.2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html
new file mode 100644
index 0000000000..c140a2668b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.zero.1</h1>
+<p class="desc">strokeRect of 0x0 pixels draws nothing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect of 0x0 pixels draws nothing");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.strokeRect(50, 25, 0, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html
new file mode 100644
index 0000000000..f17620a302
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.zero.2</h1>
+<p class="desc">strokeRect of 0x0 pixels draws nothing, including caps and joins</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect of 0x0 pixels draws nothing, including caps and joins");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(50, 25, 0, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html
new file mode 100644
index 0000000000..e671ae4116
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.zero.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.zero.3</h1>
+<p class="desc">strokeRect of Nx0 pixels draws a straight line</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect of Nx0 pixels draws a straight line");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html
new file mode 100644
index 0000000000..ff3c4040b3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.zero.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.zero.4</h1>
+<p class="desc">strokeRect of Nx0 pixels draws a closed line with no caps</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect of Nx0 pixels draws a closed line with no caps");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html
new file mode 100644
index 0000000000..809781ab43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeRect.zero.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeRect.zero.5</h1>
+<p class="desc">strokeRect of Nx0 pixels draws a closed line with joins</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeRect of Nx0 pixels draws a closed line with joins");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 250;
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html
new file mode 100644
index 0000000000..481d6fe9e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.CSSHSL</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.CSSHSL</h1>
+<p class="desc">CSSHSL works as color input</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("CSSHSL works as color input");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = new CSSHSL(CSS.deg(180), 0.5, 0.5);
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 64,191,191,255, 3);
+
+ const color = new CSSHSL(CSS.deg(180), 1, 1);
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#ffffff', "ctx.fillStyle", "'#ffffff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+ color.l = 0.5;
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#00ffff', "ctx.fillStyle", "'#00ffff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,255,255);
+
+ ctx.fillStyle = new CSSRGB(1, 0, 1).toHSL();
+ _assertSame(ctx.fillStyle, '#ff00ff', "ctx.fillStyle", "'#ff00ff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,0,255,255);
+
+ color.h = CSS.deg(120);
+ color.s = 1;
+ color.l = 0.5;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html
new file mode 100644
index 0000000000..cfdb603d5d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.CSSRGB</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.CSSRGB</h1>
+<p class="desc">CSSRGB works as color input</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("CSSRGB works as color input");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = new CSSRGB(1, 0, 1);
+ _assertSame(ctx.fillStyle, '#ff00ff', "ctx.fillStyle", "'#ff00ff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,0,255,255);
+
+ const color = new CSSRGB(0, CSS.percent(50), 0);
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#008000', "ctx.fillStyle", "'#008000'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,128,0,255);
+ color.g = 0;
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#000000', "ctx.fillStyle", "'#000000'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+
+ color.alpha = 0;
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, 'rgba(0, 0, 0, 0)', "ctx.fillStyle", "'rgba(0, 0, 0, 0)'");
+ ctx.reset();
+ color.alpha = 0.5;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,128);
+
+ ctx.fillStyle = new CSSHSL(CSS.deg(0), 1, 1).toRGB();
+ _assertSame(ctx.fillStyle, '#ffffff', "ctx.fillStyle", "'#ffffff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+
+ color.alpha = 1;
+ color.g = 1;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.html
new file mode 100644
index 0000000000..ae6507350c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.colorObject</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.colorObject</h1>
+<p class="desc">ctx.fillStyle works with color objects</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("ctx.fillStyle works with color objects");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = {r: 1, g: 0, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,0,0,255);
+ ctx.fillStyle = {r: 0, g: 0, b: 1};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,255,255);
+ ctx.fillStyle = {r: 0.2, g: 0.4, b: 0.6};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 51,102,153,255);
+ ctx.fillStyle = {r: 0, g: 1, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ ctx.fillStyle = {r: -1, g: 0, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+ ctx.fillStyle = {r: 0, g: 2, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.transparency.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.transparency.html
new file mode 100644
index 0000000000..b48715f093
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colorObject.transparency.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.colorObject.transparency</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.colorObject.transparency</h1>
+<p class="desc">ctx.fillStyle with color objects has transparency</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("ctx.fillStyle with color objects has transparency");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: -1};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 0.5};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,128);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 1};
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.currentcolor.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.currentcolor.html
new file mode 100644
index 0000000000..191395a20b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.currentcolor.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.colormix.currentcolor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.colormix.currentcolor</h1>
+<p class="desc">color-mix works as color input with currentcolor</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("color-mix works as color input with currentcolor");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('style', 'color: magenta');
+ ctx.fillStyle = "color-mix(in srgb, black, currentcolor)";
+ _assertSame(ctx.fillStyle, 'color(srgb 0.5 0 0.5)', "ctx.fillStyle", "'color(srgb 0.5 0 0.5)'");
+ ctx.strokeStyle = "color-mix(in srgb, black, currentcolor)";
+ _assertSame(ctx.strokeStyle, 'color(srgb 0.5 0 0.5)', "ctx.strokeStyle", "'color(srgb 0.5 0 0.5)'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.html
new file mode 100644
index 0000000000..1faa6c0a9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.colormix.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.colormix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.colormix</h1>
+<p class="desc">color-mix works as color input</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("color-mix works as color input");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = "color-mix(in srgb, red, blue)";
+ _assertSame(ctx.fillStyle, 'color(srgb 0.5 0 0.5)', "ctx.fillStyle", "'color(srgb 0.5 0 0.5)'");
+ ctx.fillStyle = "color-mix(in srgb, red, color(srgb 1 0 0))";
+ _assertSame(ctx.fillStyle, 'color(srgb 1 0 0)', "ctx.fillStyle", "'color(srgb 1 0 0)'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.default.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.default.html
new file mode 100644
index 0000000000..1bd3e2d4ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.default.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.fillStyle, '#000000', "ctx.fillStyle", "'#000000'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html
new file mode 100644
index 0000000000..423293e1b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.get.halftransparent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.get.halftransparent</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(255,255,255,0.5)';
+ _assertSame(ctx.fillStyle, 'rgba(255, 255, 255, 0.5)', "ctx.fillStyle", "'rgba(255, 255, 255, 0.5)'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html
new file mode 100644
index 0000000000..ec63d7662d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.get.semitransparent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.get.semitransparent</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(255,255,255,0.45)';
+ assert_regexp_match(ctx.fillStyle, /^rgba\(255, 255, 255, 0\.4\d+\)$/);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.solid.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.solid.html
new file mode 100644
index 0000000000..bcdd57a7ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.solid.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.get.solid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.get.solid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#fa0';
+ _assertSame(ctx.fillStyle, '#ffaa00', "ctx.fillStyle", "'#ffaa00'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.transparent.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.transparent.html
new file mode 100644
index 0000000000..21931aaf23
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.get.transparent.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.get.transparent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.get.transparent</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0,0,0,0)';
+ _assertSame(ctx.fillStyle, 'rgba(0, 0, 0, 0)', "ctx.fillStyle", "'rgba(0, 0, 0, 0)'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidstring.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidstring.html
new file mode 100644
index 0000000000..9fb83063f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidstring.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.invalidstring</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.invalidstring</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = 'invalid';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidtype.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidtype.html
new file mode 100644
index 0000000000..84d8fbd3ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.invalidtype.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.invalidtype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.invalidtype</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = null;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html
new file mode 100644
index 0000000000..87b5bc9371
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html
new file mode 100644
index 0000000000..746c358dbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0% / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html
new file mode 100644
index 0000000000..b8a9cd5a09
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html
new file mode 100644
index 0000000000..d5e58b9321
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html
new file mode 100644
index 0000000000..85bbb802b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html
new file mode 100644
index 0000000000..154bdcd49a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-6.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html
new file mode 100644
index 0000000000..5cf81e41a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-7</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-7</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-7.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(133.33333333grad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html
new file mode 100644
index 0000000000..17d0782df1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-8</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-8.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(2.0943951024rad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html
new file mode 100644
index 0000000000..2f4b1e8e1a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsl-9</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-9</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsl-9.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(0.3333333333turn, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html
new file mode 100644
index 0000000000..bc70e21d62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html
new file mode 100644
index 0000000000..7f77498531
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0% / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html
new file mode 100644
index 0000000000..c33a50a946
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html
new file mode 100644
index 0000000000..3d0cafc66b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html
new file mode 100644
index 0000000000..a70613b49f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html
new file mode 100644
index 0000000000..8c46d887ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-6.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html
new file mode 100644
index 0000000000..b6b4760086
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-7</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-7</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-7.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(133.33333333grad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html
new file mode 100644
index 0000000000..7933d47fd2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-8</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-8.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(2.0943951024rad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html
new file mode 100644
index 0000000000..8a4e29d40e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-hsla-9</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-9</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-hsla-9.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(0.3333333333turn, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html
new file mode 100644
index 0000000000..632b7f57fb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgb-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgb-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255.0, 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html
new file mode 100644
index 0000000000..1d3e683b35
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgb-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgb-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html
new file mode 100644
index 0000000000..8a6f352350
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgb-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgb-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html
new file mode 100644
index 0000000000..1fdf9ecf92
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgb-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgb-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html
new file mode 100644
index 0000000000..a1d99d5e24
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgb-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgb-5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0 / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html
new file mode 100644
index 0000000000..ad2c5f5484
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgb-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgb-6.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0 / 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html
new file mode 100644
index 0000000000..f394dbfb2f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgba-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgba-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255.0, 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html
new file mode 100644
index 0000000000..5529bc1462
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgba-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgba-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html
new file mode 100644
index 0000000000..82047a5698
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgba-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgba-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html
new file mode 100644
index 0000000000..5fea546f10
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgba-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgba-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html
new file mode 100644
index 0000000000..d048566522
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgba-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgba-5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0 / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html
new file mode 100644
index 0000000000..28feb2eb17
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.css-color-4-rgba-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.css-color-4-rgba-6.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0 / 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.png
new file mode 100644
index 0000000000..c5661de82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.basic.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.basic.html
new file mode 100644
index 0000000000..a1481e36e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.basic.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.current.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.current.basic</h1>
+<p class="desc">currentColor is computed from the canvas element</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("currentColor is computed from the canvas element");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('style', 'color: #0f0');
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'currentColor';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.changed.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.changed.html
new file mode 100644
index 0000000000..2f4d0fe4f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.changed.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.current.changed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.current.changed</h1>
+<p class="desc">currentColor is computed when the attribute is set, not when it is painted</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("currentColor is computed when the attribute is set, not when it is painted");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('style', 'color: #0f0');
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'currentColor';
+ canvas.setAttribute('style', 'color: #f00');
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.html
new file mode 100644
index 0000000000..96b070c8c1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.current.removed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.current.removed</h1>
+<p class="desc">currentColor is solid black when the canvas element is not in a document</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.current.removed.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("currentColor is solid black when the canvas element is not in a document");
+_addTest(function(canvas, ctx) {
+
+ // Try not to let it undetectably incorrectly pick up opaque-black
+ // from other parts of the document:
+ document.body.parentNode.setAttribute('style', 'color: #f00');
+ document.body.setAttribute('style', 'color: #f00');
+ canvas.setAttribute('style', 'color: #f00');
+
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillStyle = 'currentColor';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.drawImage(canvas2, 0, 0);
+
+ document.body.parentNode.removeAttribute('style');
+ document.body.removeAttribute('style');
+
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.png
new file mode 100644
index 0000000000..d638d03386
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.current.removed.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html
new file mode 100644
index 0000000000..017bfc88c2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hex3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hex3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hex3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html
new file mode 100644
index 0000000000..c8704edbb2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hex4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hex4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hex4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#0f0f';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html
new file mode 100644
index 0000000000..9644a46a0c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hex6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hex6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hex6.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#00fF00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex6.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html
new file mode 100644
index 0000000000..b2dd06982d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hex8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hex8</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hex8.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#00ff00ff';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hex8.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html
new file mode 100644
index 0000000000..ceb3da52e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html
new file mode 100644
index 0000000000..22e67e33d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl( -240 , 100% , 50% )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html
new file mode 100644
index 0000000000..e182952fbf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(360120, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html
new file mode 100644
index 0000000000..b320c1c98b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(-360240, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html
new file mode 100644
index 0000000000..1264f626de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html
new file mode 100644
index 0000000000..e0fc787559
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-6.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(+120, +100%, +50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html
new file mode 100644
index 0000000000..59d66c383c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-clamp-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 200%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html
new file mode 100644
index 0000000000..1a1939e47a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-clamp-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, -200%, 49.9%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 127,127,127,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.png
new file mode 100644
index 0000000000..88fd827985
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html
new file mode 100644
index 0000000000..56f3a0a8b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-clamp-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-clamp-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-clamp-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, 200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.png
new file mode 100644
index 0000000000..bf48767a88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html
new file mode 100644
index 0000000000..af9d11e678
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsl-clamp-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsl-clamp-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsl-clamp-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, -200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.png
new file mode 100644
index 0000000000..d638d03386
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html
new file mode 100644
index 0000000000..dbc738ffa7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 50%, 0.499)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.png
new file mode 100644
index 0000000000..2aa6265f06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html
new file mode 100644
index 0000000000..aa21789b02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla( 120.0 , 100.0% , 50.0% , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html
new file mode 100644
index 0000000000..2acac26e1a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-clamp-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 200%, 50%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html
new file mode 100644
index 0000000000..0f32fb5474
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-clamp-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, -200%, 49.9%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 127,127,127,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.png
new file mode 100644
index 0000000000..88fd827985
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html
new file mode 100644
index 0000000000..4bc134aec5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-clamp-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-clamp-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-clamp-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 200%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.png
new file mode 100644
index 0000000000..bf48767a88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html
new file mode 100644
index 0000000000..f8b2382755
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-clamp-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-clamp-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-clamp-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, -200%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.png
new file mode 100644
index 0000000000..d638d03386
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html
new file mode 100644
index 0000000000..9c5e2258b9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-clamp-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-clamp-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-clamp-5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 50%, 2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html
new file mode 100644
index 0000000000..153515eedd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.hsla-clamp-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.hsla-clamp-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.hsla-clamp-6.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 0%, -2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.html
new file mode 100644
index 0000000000..65d0d2020c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.html4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.html4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.html4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'limE';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.html4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html
new file mode 100644
index 0000000000..4046f825a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50% / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html
new file mode 100644
index 0000000000..2075f8e459
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0 100% 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html
new file mode 100644
index 0000000000..53bbf6c7ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100% 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html
new file mode 100644
index 0000000000..e8be93b59d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0 100% 50% /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html
new file mode 100644
index 0000000000..b8938adeb2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50% /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html
new file mode 100644
index 0000000000..7104ca6a84
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsla-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 100%, 50% / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html
new file mode 100644
index 0000000000..c340e7445d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsla-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0 100% 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html
new file mode 100644
index 0000000000..3f94ec16ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-hsla-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsla-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 100% 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html
new file mode 100644
index 0000000000..69503593fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, 0, 0 / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html
new file mode 100644
index 0000000000..96af643ee8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255 0 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html
new file mode 100644
index 0000000000..a2691acaf1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html
new file mode 100644
index 0000000000..eb5f56692a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(0 0 0 /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html
new file mode 100644
index 0000000000..7de9dd4911
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(0, 0, 0 /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html
new file mode 100644
index 0000000000..20b889c5cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgba-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgba-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0 / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html
new file mode 100644
index 0000000000..908545cebe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgba-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgba-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255 0 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html
new file mode 100644
index 0000000000..851314f643
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.css-color-4-rgba-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgba-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html
new file mode 100644
index 0000000000..9aba392276
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#f'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html
new file mode 100644
index 0000000000..361db1de43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#f0'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html
new file mode 100644
index 0000000000..7df089d840
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#g00'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html
new file mode 100644
index 0000000000..6089675b81
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg00'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html
new file mode 100644
index 0000000000..488daf4690
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#ff000'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html
new file mode 100644
index 0000000000..ec0def2e10
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex6</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg0000'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html
new file mode 100644
index 0000000000..2b07b8dc9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex7</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex7</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#ff0000f'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html
new file mode 100644
index 0000000000..f886d4a67c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hex8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hex8</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg0000ff'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html
new file mode 100644
index 0000000000..153f9cb513
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsl-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0%, 100%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html
new file mode 100644
index 0000000000..7a2bd4f930
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsl-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(z, 100%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html
new file mode 100644
index 0000000000..8ad0f54264
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsl-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 0, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html
new file mode 100644
index 0000000000..780b83b383
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsl-4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html
new file mode 100644
index 0000000000..ad5944f1c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsl-5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100.%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html
new file mode 100644
index 0000000000..948a9d8a36
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsl-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsl-6</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50%,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html
new file mode 100644
index 0000000000..7a4bdb318f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsla-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0%, 100%, 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html
new file mode 100644
index 0000000000..4164de3bbd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsla-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 0, 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html
new file mode 100644
index 0000000000..109a22cdf9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.hsla-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.hsla-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 0, 50%, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html
new file mode 100644
index 0000000000..acdd4d4c8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.name-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.name-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'darkbrown'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html
new file mode 100644
index 0000000000..292f909bcd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.name-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.name-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'firebrick1'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html
new file mode 100644
index 0000000000..f47ec43f55
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.name-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.name-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'red blue'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html
new file mode 100644
index 0000000000..d15d787f63
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.name-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.name-4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '"red"'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html
new file mode 100644
index 0000000000..ce391d0069
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.name-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.name-5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '"red'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html
new file mode 100644
index 0000000000..934f725dd3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgb-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgb-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255.0, 0, 0,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html
new file mode 100644
index 0000000000..f92a06b450
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgb-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgb-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(100%, 0, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html
new file mode 100644
index 0000000000..8ebde1782a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgb-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgb-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, - 1, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html
new file mode 100644
index 0000000000..6e3d135f41
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgba-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgba-1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(100%, 0, 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html
new file mode 100644
index 0000000000..a6a61002da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgba-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgba-2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1. 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html
new file mode 100644
index 0000000000..464d562b2f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgba-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgba-3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1.)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html
new file mode 100644
index 0000000000..815ce2f8b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgba-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgba-4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, '; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html
new file mode 100644
index 0000000000..33c3e33dfc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.invalid.rgba-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.invalid.rgba-5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html
new file mode 100644
index 0000000000..0432a3bbd4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-clamp-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-1000, 1000, -1000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html
new file mode 100644
index 0000000000..cf81e3c73f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-clamp-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-200%, 200%, -200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html
new file mode 100644
index 0000000000..b3c609fbee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-clamp-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-clamp-3</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-clamp-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-2147483649, 4294967298, -18446744073709551619)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html
new file mode 100644
index 0000000000..60aa8563bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-clamp-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-clamp-4</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-clamp-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-1000000000000000000000000000000000000000, 1000000000000000000000000000000000000000, -1000000000000000000000000000000000000000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html
new file mode 100644
index 0000000000..242ca3933d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-clamp-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-clamp-5</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-clamp-5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html
new file mode 100644
index 0000000000..201874c27d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-eof</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-eof</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-eof.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html
new file mode 100644
index 0000000000..0ce1db836f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-num</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-num</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-num.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0,255,0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html
new file mode 100644
index 0000000000..9b3de61672
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgb-percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgb-percent</h1>
+<p class="desc"></p>
+
+<p class="notes">CSS3 Color says "The integer value 255 corresponds to 100%". (In particular, it is not 254...)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgb-percent.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0% ,100% ,0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html
new file mode 100644
index 0000000000..587253ad69
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-clamp-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, -2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html
new file mode 100644
index 0000000000..4e8156e60a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-clamp-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html
new file mode 100644
index 0000000000..5f07d38b68
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-eof</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-eof</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-eof.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 1';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html
new file mode 100644
index 0000000000..0c329c96ea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-num-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-num-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-num-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , .499 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.png
new file mode 100644
index 0000000000..2aa6265f06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html
new file mode 100644
index 0000000000..384a7f412a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-num-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-num-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-num-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 0.499 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.png
new file mode 100644
index 0000000000..2aa6265f06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html
new file mode 100644
index 0000000000..60ee007577
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-percent</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-percent.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0%,100%,0%,0.499)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.png
new file mode 100644
index 0000000000..2aa6265f06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html
new file mode 100644
index 0000000000..eaec0debcb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-solid-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-solid-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-solid-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html
new file mode 100644
index 0000000000..947bbbce8d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-solid-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-solid-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-solid-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 1.0 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html
new file mode 100644
index 0000000000..052a12beae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-solid-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-solid-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-solid-3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , +1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html
new file mode 100644
index 0000000000..ee9cd4e34e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.rgba-solid-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.rgba-solid-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.rgba-solid-4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( -0 , 255 , +0 , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.png
new file mode 100644
index 0000000000..2733836c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html
new file mode 100644
index 0000000000..0ff839b8cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.svg-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.svg-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.svg-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'gray';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 128,128,128,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.png
new file mode 100644
index 0000000000..5bc39cc699
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html
new file mode 100644
index 0000000000..141f4bfe46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.svg-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.svg-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.svg-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 128,128,128,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.png
new file mode 100644
index 0000000000..5bc39cc699
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.system.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.system.html
new file mode 100644
index 0000000000..3a56389973
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.system.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.system</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.system</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'ThreeDDarkShadow';
+ assert_regexp_match(ctx.fillStyle, /^#(?!(FF0000|ff0000|f00)$)/); // test that it's not red
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html
new file mode 100644
index 0000000000..5b9a834c0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.transparent-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.transparent-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.transparent-1.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'transparent';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html
new file mode 100644
index 0000000000..a077534c23
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.parse.transparent-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.transparent-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.fillStyle.parse.transparent-2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'TrAnSpArEnT';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.png
new file mode 100644
index 0000000000..eeedd0ff05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html
new file mode 100644
index 0000000000..2a12b05839
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.fillStyle.toStringFunctionCallback</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.toStringFunctionCallback</h1>
+<p class="desc">Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = { toString: function() { return "#008000"; } };
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ ctx.fillStyle = {};
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ ctx.fillStyle = 800000;
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ assert_throws_js(TypeError, function() { ctx.fillStyle = { toString: function() { throw new TypeError; } }; });
+ ctx.strokeStyle = { toString: function() { return "#008000"; } };
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ ctx.strokeStyle = {};
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ ctx.strokeStyle = 800000;
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ assert_throws_js(TypeError, function() { ctx.strokeStyle = { toString: function() { throw new TypeError; } }; });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html
new file mode 100644
index 0000000000..1a4cde4146
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.conic.invalid.inputs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.conic.invalid.inputs</h1>
+<p class="desc">Conic gradient function with invalid inputs</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Conic gradient function with invalid inputs");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(-Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(NaN, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, -Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, NaN, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, Infinity, Infinity); });
+
+ const g = ctx.createConicGradient(0, 0, 25);
+ assert_throws_js(TypeError, function() { g.addColorStop(-Infinity, '#f00'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(NaN, '#f00'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, -Infinity); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, NaN); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html
new file mode 100644
index 0000000000..ba85463b41
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.conic.negative.rotation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.conic.negative.rotation</h1>
+<p class="desc">Conic gradient with negative rotation</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Conic gradient with negative rotation");
+_addTest(function(canvas, ctx) {
+
+ const g = ctx.createConicGradient(-Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,15, 255,0,0,255, 3);
+ _assertPixelApprox(canvas, 75,40, 0,255,0,255, 3);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html
new file mode 100644
index 0000000000..f8cebbb0d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.conic.positive.rotation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.conic.positive.rotation</h1>
+<p class="desc">Conic gradient with positive rotation</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Conic gradient with positive rotation");
+_addTest(function(canvas, ctx) {
+
+ const g = ctx.createConicGradient(3*Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,15, 255,0,0,255, 3);
+ _assertPixelApprox(canvas, 75,40, 0,255,0,255, 3);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.empty.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.empty.html
new file mode 100644
index 0000000000..dcc7575254
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.empty.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.empty</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html
new file mode 100644
index 0000000000..13f48f37bf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.alpha</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.gradient.interpolate.alpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(0,0,255, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 191,191,63,255, 3);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 3);
+ _assertPixelApprox(canvas, 75,25, 63,63,191,255, 3);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.png
new file mode 100644
index 0000000000..af5ac0f07d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.html
new file mode 100644
index 0000000000..3f7e27abe0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.color</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.color</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.gradient.interpolate.color.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 191,191,63,255, 3);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 3);
+ _assertPixelApprox(canvas, 75,25, 63,63,191,255, 3);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.png
new file mode 100644
index 0000000000..af5ac0f07d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.color.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html
new file mode 100644
index 0000000000..0d635ed671
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.coloralpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.coloralpha</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.gradient.interpolate.coloralpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(255,255,0, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 190,190,65,65, 3);
+ _assertPixelApprox(canvas, 50,25, 126,126,128,128, 3);
+ _assertPixelApprox(canvas, 75,25, 62,62,192,192, 3);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.png
new file mode 100644
index 0000000000..552e6ee44b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html
new file mode 100644
index 0000000000..9e62f3436c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.multiple</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.gradient.interpolate.multiple.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.5, '#0ff');
+ g.addColorStop(1, '#f0f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ _assertPixelApprox(canvas, 50,25, 127,255,127,255, 3);
+ _assertPixelApprox(canvas, 100,25, 0,255,255,255, 3);
+ _assertPixelApprox(canvas, 150,25, 127,127,255,255, 3);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.png
new file mode 100644
index 0000000000..86122450d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.multiple.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.outside.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.outside.html
new file mode 100644
index 0000000000..b46a7bed36
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.outside.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.outside</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(25, 0, 75, 0);
+ g.addColorStop(0.4, '#0f0');
+ g.addColorStop(0.6, '#0f0');
+
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 20,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html
new file mode 100644
index 0000000000..099a3ea81a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.overlap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.overlap</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.gradient.interpolate.overlap.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.25, '#00f');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#ff0');
+ g.addColorStop(0.5, '#00f');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.75, '#00f');
+ g.addColorStop(0.75, '#f00');
+ g.addColorStop(0.75, '#ff0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ _assertPixelApprox(canvas, 49,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 51,25, 255,255,0,255, 16);
+ _assertPixelApprox(canvas, 99,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 101,25, 255,255,0,255, 16);
+ _assertPixelApprox(canvas, 149,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 151,25, 255,255,0,255, 16);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.png
new file mode 100644
index 0000000000..5c2bb964e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html
new file mode 100644
index 0000000000..a4a2955d3b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.overlap2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.overlap2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
+ for (var p = 0; p < ps.length; ++p)
+ {
+ g.addColorStop(ps[p], '#0f0');
+ for (var i = 0; i < 15; ++i)
+ g.addColorStop(ps[p], '#f00');
+ g.addColorStop(ps[p], '#0f0');
+ }
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 30,25, 0,255,0,255);
+ _assertPixel(canvas, 40,25, 0,255,0,255);
+ _assertPixel(canvas, 60,25, 0,255,0,255);
+ _assertPixel(canvas, 80,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.solid.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.solid.html
new file mode 100644
index 0000000000..9ac31626df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.solid.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.solid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.solid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html
new file mode 100644
index 0000000000..80302761d6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.vertical</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.vertical</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.gradient.interpolate.vertical.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,12, 191,191,63,255, 10);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 5);
+ _assertPixelApprox(canvas, 50,37, 63,63,191,255, 10);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.png
new file mode 100644
index 0000000000..37d6a00c62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.vertical.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html
new file mode 100644
index 0000000000..7a8892db11
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.zerosize.fill</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.zerosize.fill</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ _assertPixel(canvas, 40,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html
new file mode 100644
index 0000000000..7696cefdd0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.zerosize.fillRect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.zerosize.fillRect</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 40,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html
new file mode 100644
index 0000000000..98ef6c3425
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.zerosize.fillText</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.zerosize.fillText</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.fillText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html
new file mode 100644
index 0000000000..283e3874ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.zerosize.stroke</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.zerosize.stroke</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.rect(20, 20, 60, 10);
+ ctx.stroke();
+ _assertPixel(canvas, 19,19, 0,255,0,255);
+ _assertPixel(canvas, 20,19, 0,255,0,255);
+ _assertPixel(canvas, 21,19, 0,255,0,255);
+ _assertPixel(canvas, 19,20, 0,255,0,255);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ _assertPixel(canvas, 21,20, 0,255,0,255);
+ _assertPixel(canvas, 19,21, 0,255,0,255);
+ _assertPixel(canvas, 20,21, 0,255,0,255);
+ _assertPixel(canvas, 21,21, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html
new file mode 100644
index 0000000000..7d243ecbc4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.zerosize.strokeRect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.zerosize.strokeRect</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.strokeRect(20, 20, 60, 10);
+ _assertPixel(canvas, 19,19, 0,255,0,255);
+ _assertPixel(canvas, 20,19, 0,255,0,255);
+ _assertPixel(canvas, 21,19, 0,255,0,255);
+ _assertPixel(canvas, 19,20, 0,255,0,255);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ _assertPixel(canvas, 21,20, 0,255,0,255);
+ _assertPixel(canvas, 19,21, 0,255,0,255);
+ _assertPixel(canvas, 20,21, 0,255,0,255);
+ _assertPixel(canvas, 21,21, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html
new file mode 100644
index 0000000000..bab7c6b6d9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.interpolate.zerosize.strokeText</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.interpolate.zerosize.strokeText</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.strokeText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html
new file mode 100644
index 0000000000..89d0092715
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.linear.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.linear.nonfinite</h1>
+<p class="desc">createLinearGradient() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createLinearGradient() throws TypeError if arguments are not finite");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(-Infinity, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(NaN, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, -Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, NaN, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, -Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, NaN, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, Infinity, Infinity); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.1.html
new file mode 100644
index 0000000000..0ae3220f06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.linear.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.linear.transform.1</h1>
+<p class="desc">Linear gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Linear gradient coordinates are relative to the coordinate space at the time of filling");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.2.html
new file mode 100644
index 0000000000..8f761c666f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.linear.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.linear.transform.2</h1>
+<p class="desc">Linear gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Linear gradient coordinates are relative to the coordinate space at the time of filling");
+_addTest(function(canvas, ctx) {
+
+ ctx.translate(100, 0);
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-150, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.3.html
new file mode 100644
index 0000000000..fdd1e0e9a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.linear.transform.3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.linear.transform.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.linear.transform.3</h1>
+<p class="desc">Linear gradient transforms do not experience broken caching effects</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Linear gradient transforms do not experience broken caching effects");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.compare.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.compare.html
new file mode 100644
index 0000000000..9ff3e607c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.compare.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.compare</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.compare</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ var g2 = ctx.createLinearGradient(0, 0, 100, 0);
+ _assertDifferent(g1, g2, "g1", "g2");
+ ctx.fillStyle = g1;
+ _assertSame(ctx.fillStyle, g1, "ctx.fillStyle", "g1");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html
new file mode 100644
index 0000000000..9c30d9cbac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.crosscanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.crosscanvas</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = document.createElement('canvas').getContext('2d').createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.html
new file mode 100644
index 0000000000..95cc893671
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.current</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.current</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.gradient.object.current.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ canvas.setAttribute('style', 'color: #f00');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'currentColor');
+ g.addColorStop(1, 'currentColor');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.png b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.png
new file mode 100644
index 0000000000..d638d03386
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.current.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html
new file mode 100644
index 0000000000..2be7b3d6fd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.invalidcolor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.invalidcolor</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, ""); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'null'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'undefined'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, null); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, undefined); });
+
+ var g = ctx.createRadialGradient(0, 0, 0, 100, 0, 0);
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, ""); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'null'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'undefined'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, null); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, undefined); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html
new file mode 100644
index 0000000000..76aaed7115
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.invalidoffset</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.invalidoffset</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ assert_throws_dom("INDEX_SIZE_ERR", function() { g.addColorStop(-1, '#000'); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { g.addColorStop(2, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(Infinity, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(-Infinity, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(NaN, '#000'); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.return.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.return.html
new file mode 100644
index 0000000000..c32312142d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.return.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.return</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.return</h1>
+<p class="desc">createLinearGradient() and createRadialGradient() returns objects implementing CanvasGradient</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createLinearGradient() and createRadialGradient() returns objects implementing CanvasGradient");
+_addTest(function(canvas, ctx) {
+
+ window.CanvasGradient.prototype.thisImplementsCanvasGradient = true;
+
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ _assertDifferent(g1.addColorStop, undefined, "g1.addColorStop", "undefined");
+ _assertSame(g1.thisImplementsCanvasGradient, true, "g1.thisImplementsCanvasGradient", "true");
+
+ var g2 = ctx.createRadialGradient(0, 0, 10, 0, 0, 20);
+ _assertDifferent(g2.addColorStop, undefined, "g2.addColorStop", "undefined");
+ _assertSame(g2.thisImplementsCanvasGradient, true, "g2.thisImplementsCanvasGradient", "true");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.type.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.type.html
new file mode 100644
index 0000000000..37c77d2f2c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.type.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.type</h1>
+<p class="desc">window.CanvasGradient exists and has the right properties</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("window.CanvasGradient exists and has the right properties");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.CanvasGradient, undefined, "window.CanvasGradient", "undefined");
+ _assertDifferent(window.CanvasGradient.prototype.addColorStop, undefined, "window.CanvasGradient.prototype.addColorStop", "undefined");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.update.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.update.html
new file mode 100644
index 0000000000..ae78d0d78f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.object.update.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.object.update</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.object.update</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createLinearGradient(-100, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ g.addColorStop(0.1, '#0f0');
+ g.addColorStop(0.9, '#0f0');
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html
new file mode 100644
index 0000000000..d32e972cc5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.behind</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.behind</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html
new file mode 100644
index 0000000000..b9774aeba6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.beside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.beside</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html
new file mode 100644
index 0000000000..15808ee50e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.bottom</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.bottom</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html
new file mode 100644
index 0000000000..067f129983
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.cylinder</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.cylinder</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.front.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.front.html
new file mode 100644
index 0000000000..88ecdb9810
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.front.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.front</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.front</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html
new file mode 100644
index 0000000000..046e4d97b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.shape1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.shape1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(30+tol, 40);
+ ctx.lineTo(110, -20+tol);
+ ctx.lineTo(110, 100-tol);
+ ctx.fill();
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html
new file mode 100644
index 0000000000..1c7660ac99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.shape2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.shape2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(30-tol, 40);
+ ctx.lineTo(110, -20-tol);
+ ctx.lineTo(110, 100+tol);
+ ctx.fill();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.top.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.top.html
new file mode 100644
index 0000000000..6760b18db7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.top.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.cone.top</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.cone.top</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.equal.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.equal.html
new file mode 100644
index 0000000000..1ff7c44193
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.equal.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.equal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.equal</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside1.html
new file mode 100644
index 0000000000..00ece5750e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.inside1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.inside1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside2.html
new file mode 100644
index 0000000000..be9c1a810a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.inside2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.inside2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside3.html
new file mode 100644
index 0000000000..5e9bd4c721
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.inside3.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.inside3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.inside3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.993, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.negative.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.negative.html
new file mode 100644
index 0000000000..d86812b68c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.negative.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.negative</h1>
+<p class="desc">createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html
new file mode 100644
index 0000000000..0c16b41540
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.nonfinite</h1>
+<p class="desc">createRadialGradient() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createRadialGradient() throws TypeError if arguments are not finite");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, NaN, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, NaN, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, NaN, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, NaN, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside1.html
new file mode 100644
index 0000000000..ea9dfdb3bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.outside1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.outside1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html
new file mode 100644
index 0000000000..b07fd02518
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.outside2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.outside2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html
new file mode 100644
index 0000000000..7c19baf5c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.outside3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.outside3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.001, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch1.html
new file mode 100644
index 0000000000..6487fc440b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.touch1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.touch1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch2.html
new file mode 100644
index 0000000000..908a0dbc19
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch2.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.touch2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.touch2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.01, '#0f0');
+ g.addColorStop(0.99, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch3.html
new file mode 100644
index 0000000000..07f52d7363
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.touch3.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.touch3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.touch3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.1.html
new file mode 100644
index 0000000000..d0eb13c457
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.transform.1</h1>
+<p class="desc">Radial gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Radial gradient coordinates are relative to the coordinate space at the time of filling");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.2.html
new file mode 100644
index 0000000000..6e56c4c63b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.transform.2</h1>
+<p class="desc">Radial gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Radial gradient coordinates are relative to the coordinate space at the time of filling");
+_addTest(function(canvas, ctx) {
+
+ ctx.translate(100, 0);
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.3.html
new file mode 100644
index 0000000000..426021d097
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.transform.3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.gradient.radial.transform.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.gradient.radial.transform.3</h1>
+<p class="desc">Radial gradient transforms do not experience broken caching effects</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Radial gradient transforms do not experience broken caching effects");
+_addTest(function(canvas, ctx) {
+
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.animated.gif.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.animated.gif.html
new file mode 100644
index 0000000000..be69cca997
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.animated.gif.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.animated.gif</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.animated.gif</h1>
+<p class="desc">createPattern() of an animated GIF draws the first frame</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("createPattern() of an animated GIF draws the first frame");
+_addTest(function(canvas, ctx) {
+
+ deferTest();
+ step_timeout(function () {
+ var pattern = ctx.createPattern(document.getElementById('anim-gr.gif'), 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 50, 50);
+ step_timeout(t.step_func_done(function () {
+ ctx.fillRect(50, 0, 50, 50);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ }), 250);
+ }, 250);
+
+});
+</script>
+<img src="/images/anim-gr.gif" id="anim-gr.gif" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.canvas.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.canvas.html
new file mode 100644
index 0000000000..069263adff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.canvas.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.basic.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.basic.canvas</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.image.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.image.html
new file mode 100644
index 0000000000..5ebffe50f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.image.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.basic.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.basic.image</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.html
new file mode 100644
index 0000000000..f24899c302
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.basic.nocontext</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.basic.nocontext</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.type.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.type.html
new file mode 100644
index 0000000000..c510063d80
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.type.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.basic.type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.basic.type</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.CanvasPattern, undefined, "window.CanvasPattern", "undefined");
+
+ window.CanvasPattern.prototype.thisImplementsCanvasPattern = true;
+
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ _assert(pattern.thisImplementsCanvasPattern, "pattern.thisImplementsCanvasPattern");
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html
new file mode 100644
index 0000000000..fbeb7bd797
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.basic.zerocanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.basic.zerocanvas</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 0;
+ canvas.height = 10;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 10, "canvas.height", "10");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+
+ canvas.width = 10;
+ canvas.height = 0;
+ _assertSame(canvas.width, 10, "canvas.width", "10");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+
+ canvas.width = 0;
+ canvas.height = 0;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.crosscanvas.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.crosscanvas.html
new file mode 100644
index 0000000000..f93b36ddf2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.crosscanvas.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.crosscanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.crosscanvas</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('green.png');
+
+ var pattern = document.createElement('canvas').getContext('2d').createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.broken.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.broken.html
new file mode 100644
index 0000000000..2cf21746ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.broken.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.broken</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.broken</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('broken.png');
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(img, 'repeat'); });
+
+});
+</script>
+<img src="/images/broken.png" id="broken.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.emptysrc.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.emptysrc.html
new file mode 100644
index 0000000000..fb05cbb455
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.emptysrc.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.incomplete.emptysrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.incomplete.emptysrc</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('red.png');
+ img.src = "";
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.immediate.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.immediate.html
new file mode 100644
index 0000000000..375c1b49c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.immediate.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.incomplete.immediate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.incomplete.immediate</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = new Image();
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.nosrc.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.nosrc.html
new file mode 100644
index 0000000000..d43a0ca918
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.nosrc.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.incomplete.nosrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.incomplete.nosrc</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = new Image();
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.reload.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.reload.html
new file mode 100644
index 0000000000..984bd36a74
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.reload.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.incomplete.reload</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.incomplete.reload</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('yellow.png');
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm,
+ // and resets the image to the "unavailable" state.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<img src="/images/yellow.png" id="yellow.png" class="resource">
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.removedsrc.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.removedsrc.html
new file mode 100644
index 0000000000..20d5543684
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.incomplete.removedsrc.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.incomplete.removedsrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.incomplete.removedsrc</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('red.png');
+ img.removeAttribute('src');
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent-but-loading.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent-but-loading.html
new file mode 100644
index 0000000000..2af0a3ed09
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent-but-loading.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.nonexistent-but-loading</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.nonexistent-but-loading</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.createElement("img");
+ img.src = "/images/no-such-image-really.png";
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+ var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ img.src = "/images/no-such-image-really.png";
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent.html
new file mode 100644
index 0000000000..b365281179
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nonexistent.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.nonexistent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.nonexistent</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('no-such-image-really.png');
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(img, 'repeat'); });
+
+});
+</script>
+<img src="/images/no-such-image-really.png" id="no-such-image-really.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nosrc.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nosrc.html
new file mode 100644
index 0000000000..710749dd54
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.nosrc.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.nosrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.nosrc</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.createElement("img");
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+ var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.null.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.null.html
new file mode 100644
index 0000000000..8ae002d682
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.null.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.null</h1>
+<p class="desc"></p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createPattern(null, 'repeat'); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.string.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.string.html
new file mode 100644
index 0000000000..af32e63bba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.string.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.string</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.string</h1>
+<p class="desc"></p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createPattern('../images/red.png', 'repeat'); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.undefined.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.undefined.html
new file mode 100644
index 0000000000..75f50c7a4a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.undefined.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.undefined</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.undefined</h1>
+<p class="desc"></p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createPattern(undefined, 'repeat'); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zeroheight.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zeroheight.html
new file mode 100644
index 0000000000..cd12c2e883
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zeroheight.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.zeroheight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.zeroheight</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('red-zeroheight.svg');
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<img src="/images/red-zeroheight.svg" id="red-zeroheight.svg" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zerowidth.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zerowidth.html
new file mode 100644
index 0000000000..053b8ac648
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.image.zerowidth.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.image.zerowidth</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.image.zerowidth</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('red-zerowidth.svg');
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<img src="/images/red-zerowidth.svg" id="red-zerowidth.svg" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas1.html
new file mode 100644
index 0000000000..0524351fdb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.modify.canvas1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.modify.canvas1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas2.html
new file mode 100644
index 0000000000..6e50a5761c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.canvas2.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.modify.canvas2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.modify.canvas2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image1.html
new file mode 100644
index 0000000000..94f55c84f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image1.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.modify.image1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.modify.image1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ deferTest();
+ img.onload = t.step_func_done(function ()
+ {
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ });
+ img.src = '/images/red.png';
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image2.html
new file mode 100644
index 0000000000..1025d195f2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.modify.image2.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.modify.image2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.modify.image2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 100, 50);
+ deferTest();
+ img.onload = t.step_func_done(function ()
+ {
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ });
+ img.src = '/images/red.png';
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html
new file mode 100644
index 0000000000..036be9e068
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.norepeat.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.norepeat.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html
new file mode 100644
index 0000000000..dfe2b8589e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.norepeat.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.norepeat.coord1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html
new file mode 100644
index 0000000000..dfd637211d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.norepeat.coord2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.norepeat.coord2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green.png" id="green.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html
new file mode 100644
index 0000000000..5456a543da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.norepeat.coord3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.norepeat.coord3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('red.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html
new file mode 100644
index 0000000000..4df0cdfe67
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.norepeat.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.norepeat.outside</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('red.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+ ctx.fillRect(-100, 0, 100, 50);
+ ctx.fillRect(0, 50, 100, 50);
+ ctx.fillRect(100, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html
new file mode 100644
index 0000000000..f0ad70fc1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.orientation.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.orientation.canvas</h1>
+<p class="desc">Canvas patterns do not get flipped when painted</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Canvas patterns do not get flipped when painted");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 25);
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 25, 100, 25);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html
new file mode 100644
index 0000000000..b45f4ab773
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.orientation.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.orientation.image</h1>
+<p class="desc">Image patterns do not get flipped when painted</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Image patterns do not get flipped when painted");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('rrgg-256x256.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.save();
+ ctx.translate(0, -103);
+ ctx.fillRect(0, 103, 100, 50);
+ ctx.restore();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/rrgg-256x256.png" id="rrgg-256x256.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html
new file mode 100644
index 0000000000..8999ac4e44
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeat.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeat.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('green-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green-16x16.png" id="green-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html
new file mode 100644
index 0000000000..8dc6402d55
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeat.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeat.coord1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('rgrg-256x256.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/rgrg-256x256.png" id="rgrg-256x256.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html
new file mode 100644
index 0000000000..9c03d02898
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeat.coord2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeat.coord2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('ggrr-256x256.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/ggrr-256x256.png" id="ggrr-256x256.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html
new file mode 100644
index 0000000000..0dc0a865b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeat.coord3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeat.coord3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('rgrg-256x256.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/rgrg-256x256.png" id="rgrg-256x256.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html
new file mode 100644
index 0000000000..b939195877
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeat.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeat.outside</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('green-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green-16x16.png" id="green-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html
new file mode 100644
index 0000000000..8c77908cd1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeatx.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeatx.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 16);
+
+ var img = document.getElementById('green-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green-16x16.png" id="green-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html
new file mode 100644
index 0000000000..4c7fa9d498
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeatx.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeatx.coord1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('red-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.translate(0, 16);
+ ctx.fillRect(0, -16, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red-16x16.png" id="red-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html
new file mode 100644
index 0000000000..26ee85e4d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeatx.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeatx.outside</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('red-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red-16x16.png" id="red-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html
new file mode 100644
index 0000000000..c28ff155eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeaty.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeaty.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 50);
+
+ var img = document.getElementById('green-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green-16x16.png" id="green-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html
new file mode 100644
index 0000000000..7f2bb163f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeaty.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeaty.coord1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('red-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.translate(48, 0);
+ ctx.fillRect(-48, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red-16x16.png" id="red-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html
new file mode 100644
index 0000000000..7be743ec2b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.paint.repeaty.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.paint.repeaty.outside</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var img = document.getElementById('red-16x16.png');
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red-16x16.png" id="red-16x16.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.case.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.case.html
new file mode 100644
index 0000000000..d998bbeb2f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.case.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.repeat.case</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.repeat.case</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "Repeat"); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.empty.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.empty.html
new file mode 100644
index 0000000000..2810efe700
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.empty.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.repeat.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.repeat.empty</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('green-1x1.png');
+ var pattern = ctx.createPattern(img, "");
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 200, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+<img src="/images/green-1x1.png" id="green-1x1.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.html
new file mode 100644
index 0000000000..0de121a4f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.repeat.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.repeat.null</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assert(ctx.createPattern(canvas, null) != null, "ctx.createPattern(canvas, null) != null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html
new file mode 100644
index 0000000000..33d601d974
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.repeat.nullsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.repeat.nullsuffix</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "repeat\0"); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.undefined.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.undefined.html
new file mode 100644
index 0000000000..f0a7ae8488
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.undefined.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.repeat.undefined</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.repeat.undefined</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, undefined); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html
new file mode 100644
index 0000000000..cdcc7d6523
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.repeat.unrecognised</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.repeat.unrecognised</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "invalid"); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html
new file mode 100644
index 0000000000..11c9ec0ebb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.repeat.unrecognisednull</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.repeat.unrecognisednull</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "null"); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.nonexistent.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.nonexistent.html
new file mode 100644
index 0000000000..8cd3983dc3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.nonexistent.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.svgimage.nonexistent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.svgimage.nonexistent</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('no-such-image-really.png');
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(img, 'repeat'); });
+
+});
+</script>
+<svg><image xlink:href="/images/no-such-image-really.png" id="no-such-image-really.png" class="resource"></svg>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zeroheight.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zeroheight.html
new file mode 100644
index 0000000000..11c07e36de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zeroheight.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.svgimage.zeroheight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.svgimage.zeroheight</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('red-zeroheight.svg');
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<svg><image xlink:href="/images/red-zeroheight.svg" id="red-zeroheight.svg" class="resource"></svg>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zerowidth.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zerowidth.html
new file mode 100644
index 0000000000..a8b8cb1351
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.svgimage.zerowidth.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.svgimage.zerowidth</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.svgimage.zerowidth</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('red-zerowidth.svg');
+ _assertSame(ctx.createPattern(img, 'repeat'), null, "ctx.createPattern(img, 'repeat')", "null");
+
+});
+</script>
+<svg><image xlink:href="/images/red-zerowidth.svg" id="red-zerowidth.svg" class="resource"></svg>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.html
new file mode 100644
index 0000000000..21da30581d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.transform.identity</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.transform.identity</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform(new DOMMatrix());
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.html
new file mode 100644
index 0000000000..bfb22aeb14
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.transform.infinity</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.transform.infinity</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform({a: Infinity});
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.html
new file mode 100644
index 0000000000..13f0459e9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.pattern.transform.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.pattern.transform.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ assert_throws_js(TypeError, function() { pattern.setTransform({a: 1, m11: 2}); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.html
new file mode 100644
index 0000000000..308e6b54b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeStyle.colorObject</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeStyle.colorObject</h1>
+<p class="desc">ctx.strokeStyle works with color objects</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("ctx.strokeStyle works with color objects");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = {r: 1, g: 0, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 255,0,0,255);
+ ctx.strokeStyle = {r: 0, g: 0, b: 1};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,255,255);
+ ctx.strokeStyle = {r: 0.2, g: 0.4, b: 0.6};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 51,102,153,255);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ ctx.strokeStyle = {r: -1, g: 0, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+ ctx.strokeStyle = {r: 0, g: 2, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.transparency.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.transparency.html
new file mode 100644
index 0000000000..0232140eaf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colorObject.transparency.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeStyle.colorObject.transparency</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeStyle.colorObject.transparency</h1>
+<p class="desc">ctx.strokeStyle with color objects has transparency</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("ctx.strokeStyle with color objects has transparency");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: -1};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 0.5};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,255,0,128);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 1};
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colormix.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colormix.html
new file mode 100644
index 0000000000..c1971666e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.colormix.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeStyle.colormix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeStyle.colormix</h1>
+<p class="desc">color-mix works as color input</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("color-mix works as color input");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = "color-mix(in srgb, red, blue)";
+ _assertSame(ctx.strokeStyle, 'color(srgb 0.5 0 0.5)', "ctx.strokeStyle", "'color(srgb 0.5 0 0.5)'");
+ ctx.strokeStyle = "color-mix(in srgb, red, color(srgb 1 0 0))";
+ _assertSame(ctx.strokeStyle, 'color(srgb 1 0 0)', "ctx.strokeStyle", "'color(srgb 1 0 0)'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.default.html b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.default.html
new file mode 100644
index 0000000000..a432d74a42
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/fill-and-stroke-styles/2d.strokeStyle.default.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.strokeStyle.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.strokeStyle.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.strokeStyle, '#000000', "ctx.strokeStyle", "'#000000'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html
new file mode 100644
index 0000000000..42fb1ee8f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.blur.exceptions.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.blur.exceptions.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() blur.object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test exceptions on CanvasFilter() blur.object");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur'}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}}); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html
new file mode 100644
index 0000000000..b2f6a6ac97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.colorMatrix.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.colorMatrix.tentative</h1>
+<p class="desc">Test the functionality of ColorMatrix filters in CanvasFilter objects</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test the functionality of ColorMatrix filters in CanvasFilter objects");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: 'foo'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}); });
+ ctx.fillStyle = '#f00';
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [
+ 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0
+ ]});
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 25);
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 25, 50, 25);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(50, 25, 50, 25);
+ _assertPixelApprox(canvas, 10,10, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 60,10, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 10,30, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 60,30, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html
new file mode 100644
index 0000000000..b392b189f2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with discrete type");
+_addTest(function(canvas, ctx) {
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k];
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'discrete', tableValues: tableValuesR},
+ funcG: {type: 'discrete', tableValues: tableValuesG},
+ funcB: {type: 'discrete', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html
new file mode 100644
index 0000000000..e5bff7e44d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with gamma type");
+_addTest(function(canvas, ctx) {
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, amplitude, exponent, offset) {
+ return [
+ Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255,
+ ];
+ }
+
+ const amplitudes = [2, 1.1, 0.5];
+ const exponents = [5, 3, 1];
+ const offsets = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]},
+ funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]},
+ funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, amplitudes, exponents, offsets);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html
new file mode 100644
index 0000000000..ecd3830be3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.identity.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with identity type");
+_addTest(function(canvas, ctx) {
+
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'identity'},
+ funcG: {type: 'identity'},
+ funcB: {type: 'identity'},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`,
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255);
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html
new file mode 100644
index 0000000000..8708887f6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.linear.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with linear type");
+_addTest(function(canvas, ctx) {
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, slopes, intercepts) {
+ return [
+ Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255,
+ Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255,
+ Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255,
+ ];
+ }
+
+ const slopes = [0.5, 1.2, -0.2];
+ const intercepts = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]},
+ funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]},
+ funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, slopes, intercepts);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html
new file mode 100644
index 0000000000..4b296d9fd7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.table.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with table type");
+_addTest(function(canvas, ctx) {
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length - 1;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k] + (C - k/n) * n * (V[k + 1] - V[k]);
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'table', tableValues: tableValuesR},
+ funcG: {type: 'table', tableValues: tableValuesG},
+ funcB: {type: 'table', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html
new file mode 100644
index 0000000000..b80600c141
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() convolveMatrix</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test exceptions on CanvasFilter() convolveMatrix");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', divisor: 2}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); });
+ // This should not throw an error
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]});
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]});
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html
new file mode 100644
index 0000000000..8c07a72b2b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() dropShadow object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test exceptions on CanvasFilter() dropShadow object");
+_addTest(function(canvas, ctx) {
+
+ // dx
+ _assert(new CanvasFilter({name: 'dropShadow', dx: 10}), "new CanvasFilter({name: 'dropShadow', dx: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: -1}), "new CanvasFilter({name: 'dropShadow', dx: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: 0.5}), "new CanvasFilter({name: 'dropShadow', dx: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: null}), "new CanvasFilter({name: 'dropShadow', dx: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: true}), "new CanvasFilter({name: 'dropShadow', dx: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: false}), "new CanvasFilter({name: 'dropShadow', dx: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: []}), "new CanvasFilter({name: 'dropShadow', dx: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: [20]}), "new CanvasFilter({name: 'dropShadow', dx: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: '30'}), "new CanvasFilter({name: 'dropShadow', dx: '30'})");
+ // dy
+ _assert(new CanvasFilter({name: 'dropShadow', dy: 10}), "new CanvasFilter({name: 'dropShadow', dy: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: -1}), "new CanvasFilter({name: 'dropShadow', dy: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: 0.5}), "new CanvasFilter({name: 'dropShadow', dy: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: null}), "new CanvasFilter({name: 'dropShadow', dy: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: true}), "new CanvasFilter({name: 'dropShadow', dy: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: false}), "new CanvasFilter({name: 'dropShadow', dy: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: []}), "new CanvasFilter({name: 'dropShadow', dy: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: [20]}), "new CanvasFilter({name: 'dropShadow', dy: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: '30'}), "new CanvasFilter({name: 'dropShadow', dy: '30'})");
+ // floodOpacity
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 10}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: -1}), "new CanvasFilter({name: 'dropShadow', floodOpacity: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: null}), "new CanvasFilter({name: 'dropShadow', floodOpacity: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: true}), "new CanvasFilter({name: 'dropShadow', floodOpacity: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: false}), "new CanvasFilter({name: 'dropShadow', floodOpacity: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: []}), "new CanvasFilter({name: 'dropShadow', floodOpacity: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: [20]}), "new CanvasFilter({name: 'dropShadow', floodOpacity: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: '30'}), "new CanvasFilter({name: 'dropShadow', floodOpacity: '30'})");
+ // stdDeviation
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({name: 'dropShadow', stdDeviation: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: null}), "new CanvasFilter({name: 'dropShadow', stdDeviation: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: true}), "new CanvasFilter({name: 'dropShadow', stdDeviation: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: false}), "new CanvasFilter({name: 'dropShadow', stdDeviation: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: []}), "new CanvasFilter({name: 'dropShadow', stdDeviation: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({name: 'dropShadow', stdDeviation: '30'})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [20]]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [\""+(20)+"\"]]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]})");
+ // floodColor
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'red'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'red'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'})");
+
+ // dx
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: [1, 2]}); });
+ // dy
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: [1, 2]}); });
+ // floodOpacity
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: [1, 2]}); });
+ // stdDeviation
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 2, 3]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, NaN]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, Infinity]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, -Infinity]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, undefined]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 'test']}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, {}]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, [2, 3]]}); });
+ // floodColor
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 10}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: NaN}); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
new file mode 100644
index 0000000000..86c5710132
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.dropShadow.tentative</title>
+<h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
+<p class="desc">Test CanvasFilter() dropShadow object.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width=520 height=420
+ color-interpolation-filters="sRGB">
+ <rect x=0 y=0 width=100% height=50 fill="teal" />
+ <rect x=0 y=100 width=100% height=50 fill="teal" />
+ <rect x=0 y=200 width=100% height=50 fill="teal" />
+ <rect x=0 y=300 width=100% height=50 fill="teal" />
+
+ <rect x=10 y=10 width=80 height=80 fill="crimson"
+ filter="drop-shadow(2px 2px 2px black)"/>
+ <rect x=110 y=10 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 5px rgba(128, 0, 128, 0.7))"/>
+
+ <rect x=10 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px purple)"/>
+ <rect x=110 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px LinkText)"/>
+ <rect x=210 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
+ <rect x=310 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.7))"/>
+ <rect x=410 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.49))"/>
+
+ <rect x=10 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+ <rect x=110 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 5px purple)"/>
+ <rect x=210 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+ <filter id="separable-filter"
+ x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx=9 dy=12 stdDeviation="3 5" flood-color="purple"/>
+ </filter>
+ <rect x=310 y=210 width=80 height=80 fill="crimson"
+ filter="url(#separable-filter)"/>
+ <rect x=410 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+
+ <rect x=10 y=310 width=80 height=80 fill="crimson"
+ filter="drop-shadow(-5px 0px 0px purple)"/>
+ <filter id="separable-filter-degenerate"
+ x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx=0 dy=5 stdDeviation="0 3"
+ flood-color="rgba(128, 0, 128, 0.8)"/>
+ </filter>
+ <rect x=110 y=310 width=80 height=80 fill="crimson"
+ filter="url(#separable-filter-degenerate)"/>
+ <rect x=210 y=310 width=80 height=80 fill="crimson"
+ filter="drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html
new file mode 100644
index 0000000000..47bb891b3f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.dropShadow.tentative-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.dropShadow.tentative</title>
+<h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
+<p class="desc">Test CanvasFilter() dropShadow object.</p>
+<canvas id="canvas" width="520" height="420">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(0, 0, 520, 50);
+ ctx.fillRect(0, 100, 520, 50);
+ ctx.fillRect(0, 200, 520, 50);
+ ctx.fillRect(0, 300, 520, 50);
+
+ ctx.fillStyle = 'crimson';
+
+ // Parameter defaults.
+ ctx.filter = new CanvasFilter({name: 'dropShadow'});
+ ctx.fillRect(10, 10, 80, 80);
+
+ // All parameters specified.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple', floodOpacity: 0.7});
+ ctx.fillRect(110, 10, 80, 80);
+
+ // Named color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 110, 80, 80);
+
+ // System color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'LinkText'});
+ ctx.fillRect(110, 110, 80, 80);
+
+ // Numerical color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 1)'});
+ ctx.fillRect(210, 110, 80, 80);
+
+ // Transparent floodColor.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)'});
+ ctx.fillRect(310, 110, 80, 80);
+
+ // Transparent floodColor and floodOpacity.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7});
+ ctx.fillRect(410, 110, 80, 80);
+
+ // No blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 210, 80, 80);
+
+ // Single float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple'});
+ ctx.fillRect(110, 210, 80, 80);
+
+ // Single negative float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5,
+ floodColor: 'purple'});
+ ctx.fillRect(210, 210, 80, 80);
+
+ // Two floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5],
+ floodColor: 'purple'});
+ ctx.fillRect(310, 210, 80, 80);
+
+ // Two negative floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5],
+ floodColor: 'purple'});
+ ctx.fillRect(410, 210, 80, 80);
+
+ // Degenerate parameter values.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null,
+ floodColor: 'purple', floodOpacity: [2]});
+ ctx.fillRect(10, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']],
+ floodColor: 'purple', floodOpacity: '0.8'});
+ ctx.fillRect(110, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false,
+ floodColor: 'purple', floodOpacity: ['0.4']});
+ ctx.fillRect(210, 310, 80, 80);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html
new file mode 100644
index 0000000000..f9571f208e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="4 4" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html
new file mode 100644
index 0000000000..6376d07b0e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html
new file mode 100644
index 0000000000..e76613271f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="4 1" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html
new file mode 100644
index 0000000000..145cb32757
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 1],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html
new file mode 100644
index 0000000000..0f214fca9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="1 4" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html
new file mode 100644
index 0000000000..e921e0eaa6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [1, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html
new file mode 100644
index 0000000000..285a641726
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="4 0" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html
new file mode 100644
index 0000000000..fd6ac687f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 0],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html
new file mode 100644
index 0000000000..d59945b5da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="0 4" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html
new file mode 100644
index 0000000000..6442433e7c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [0, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.tentative.html
new file mode 100644
index 0000000000..c40e718d72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.tentative.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.tentative</h1>
+<p class="desc">Test CanvasFilter() object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test CanvasFilter() object");
+_addTest(function(canvas, ctx) {
+
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1, 2]});
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = new CanvasFilter([
+ {name: 'gaussianBlur', stdDeviation: 5},
+ {name: 'gaussianBlur', stdDeviation: 10}
+ ]);
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.filter = ctx.filter;
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'none';
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ ctx.filter = 'this string is not a filter and should do nothing';
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html
new file mode 100644
index 0000000000..c24cfd2398
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.turbulence.inputTypes.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.canvasFilterObject.turbulence.inputTypes.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() turbulence object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test exceptions on CanvasFilter() turbulence object");
+_addTest(function(canvas, ctx) {
+
+ const errorTestCases = [
+ {baseFrequency: {}},
+ {baseFrequency: -1},
+ {baseFrequency: [0, -1]},
+ {baseFrequency: NaN},
+ {baseFrequency: Infinity},
+ {baseFrequency: undefined},
+ {baseFrequency: -Infinity},
+ {baseFrequency: 'test'},
+
+ {numOctaves: {}},
+ {numOctaves: -1},
+ {numOctaves: NaN},
+ {numOctaves: Infinity},
+ {numOctaves: undefined},
+ {numOctaves: -Infinity},
+ {numOctaves: [1, 1]},
+ {numOctaves: 'test'},
+
+ {seed: {}},
+ {seed: NaN},
+ {seed: Infinity},
+ {seed: undefined},
+ {seed: -Infinity},
+ {seed: [1, 1]},
+ {seed: 'test'},
+
+ {stitchTiles: {}},
+ {stitchTiles: NaN},
+ {stitchTiles: Infinity},
+ {stitchTiles: undefined},
+ {stitchTiles: -Infinity},
+ {stitchTiles: [1, 1]},
+ {stitchTiles: 'test'},
+ {stitchTiles: null},
+ {stitchTiles: []},
+ {stitchTiles: [10]},
+ {stitchTiles: 30},
+ {stitchTiles: false},
+ {stitchTiles: true},
+ {stitchTiles: '10'},
+ {stitchTiles: -1},
+
+ {type: {}},
+ {type: NaN},
+ {type: Infinity},
+ {type: undefined},
+ {type: -Infinity},
+ {type: [1, 1]},
+ {type: 'test'},
+ {type: null},
+ {type: []},
+ {type: [10]},
+ {type: 30},
+ {type: false},
+ {type: true},
+ {type: '10'},
+ {type: -1},
+ ]
+
+ // null and [] = 0 when parsed as number
+ const workingTestCases = [
+ {baseFrequency: null},
+ {baseFrequency: []},
+ {baseFrequency: [10]},
+ {baseFrequency: [10, 3]},
+ {baseFrequency: 30},
+ {baseFrequency: false},
+ {baseFrequency: true},
+ {baseFrequency: '10'},
+
+ {numOctaves: null},
+ {numOctaves: []},
+ {numOctaves: [10]},
+ {numOctaves: 30},
+ {numOctaves: false},
+ {numOctaves: true},
+ {numOctaves: '10'},
+
+ {seed: null},
+ {seed: []},
+ {seed: [10]},
+ {seed: 30},
+ {seed: false},
+ {seed: true},
+ {seed: '10'},
+ {seed: -1},
+
+ {stitchTiles: 'stitch'},
+ {stitchTiles: 'noStitch'},
+
+ {type: 'fractalNoise'},
+ {type: 'turbulence'},
+ ]
+
+ for (testCase of errorTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ assert_throws_js(TypeError, function() { new CanvasFilter(filterOptions); });
+ }
+
+ for (testCase of workingTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ _assert(new CanvasFilter(filterOptions) != null, "new CanvasFilter(filterOptions) != null");
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.value.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.value.html
new file mode 100644
index 0000000000..5716b9bd16
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.value.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.value</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.filter.value</h1>
+<p class="desc">test if ctx.filter works correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test if ctx.filter works correctly");
+_addTest(function(canvas, ctx) {
+
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.save();
+ ctx.filter = 'none';
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.restore();
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'blur(10)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'blur 10px';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'inherit';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'initial';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'unset';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = '';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = null;
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = undefined;
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'blur( 5px)';
+ assert_equals(ctx.filter, 'blur( 5px)');
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic-expected.html
new file mode 100644
index 0000000000..6a6f0f6892
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.isotropic</title>
+<h1>2d.layer.anisotropic-blur.isotropic</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="4 4" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic.html
new file mode 100644
index 0000000000..4e496b7e48
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.isotropic.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.isotropic-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.isotropic</title>
+<h1>2d.layer.anisotropic-blur.isotropic</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x-expected.html
new file mode 100644
index 0000000000..b0473f2ff0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-x</title>
+<h1>2d.layer.anisotropic-blur.mostly-x</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="4 1" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x.html
new file mode 100644
index 0000000000..4217d9fad3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-x.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.mostly-x-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-x</title>
+<h1>2d.layer.anisotropic-blur.mostly-x</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 1] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y-expected.html
new file mode 100644
index 0000000000..43da016eea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-y</title>
+<h1>2d.layer.anisotropic-blur.mostly-y</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="1 4" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y.html
new file mode 100644
index 0000000000..97a44e9045
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.mostly-y.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.mostly-y-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-y</title>
+<h1>2d.layer.anisotropic-blur.mostly-y</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [1, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only-expected.html
new file mode 100644
index 0000000000..0b4d269189
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.x-only</title>
+<h1>2d.layer.anisotropic-blur.x-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="4 0" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only.html
new file mode 100644
index 0000000000..fdf604616b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.x-only.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.x-only-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.x-only</title>
+<h1>2d.layer.anisotropic-blur.x-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 0] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only-expected.html
new file mode 100644
index 0000000000..2572386412
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.y-only</title>
+<h1>2d.layer.anisotropic-blur.y-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="0 4" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only.html
new file mode 100644
index 0000000000..c7ceb63a87
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.anisotropic-blur.y-only.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.y-only-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.y-only</title>
+<h1>2d.layer.anisotropic-blur.y-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [0, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.beginLayer-options.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.beginLayer-options.html
new file mode 100644
index 0000000000..658d7e0991
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.beginLayer-options.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.beginLayer-options</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.beginLayer-options</h1>
+<p class="desc">Checks beginLayer works for different option parameter values</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Checks beginLayer works for different option parameter values");
+_addTest(function(canvas, ctx) {
+
+ ctx.beginLayer(); ctx.endLayer();
+ ctx.beginLayer(null); ctx.endLayer();
+ ctx.beginLayer(undefined); ctx.endLayer();
+ ctx.beginLayer([]); ctx.endLayer();
+ ctx.beginLayer({}); ctx.endLayer();
+
+ assert_throws_js(TypeError, function() { ctx.beginLayer(''); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(0); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(1); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(true); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(false); });
+
+ ctx.beginLayer({filter: null}); ctx.endLayer();
+ ctx.beginLayer({filter: undefined}); ctx.endLayer();
+ ctx.beginLayer({filter: []}); ctx.endLayer();
+ ctx.beginLayer({filter: {}}); ctx.endLayer();
+ ctx.beginLayer({filter: {name: "unknown"}}); ctx.endLayer();
+ ctx.beginLayer({filter: ''}); ctx.endLayer();
+
+ // These cases don't throw TypeError since they can be casted to a
+ // DOMString.
+ ctx.beginLayer({filter: 0}); ctx.endLayer();
+ ctx.beginLayer({filter: 1}); ctx.endLayer();
+ ctx.beginLayer({filter: true}); ctx.endLayer();
+ ctx.beginLayer({filter: false}); ctx.endLayer();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html
new file mode 100644
index 0000000000..6cad180f14
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.no-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.no-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur in="SourceGraphic" stdDeviation="30" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="201" y="50" width="100" height="100" fill="turquoise"/>
+ <rect x="50" y="201" width="100" height="100" fill="indigo"/>
+ <rect x="-101" y="50" width="100" height="100" fill="orange"/>
+ <rect x="50" y="-101" width="100" height="100" fill="brown"/>
+ </g>
+ </svg>`;
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ // No clipping.
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping.html
new file mode 100644
index 0000000000..b689ad39fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.no-clipping.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.blur-from-outside-canvas.no-clipping-expected.html">
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.no-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.no-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [ {name: 'gaussianBlur', stdDeviation: 30} ]});
+
+ ctx.fillStyle = 'turquoise';
+ ctx.fillRect(201, 50, 100, 100);
+ ctx.fillStyle = 'indigo';
+ ctx.fillRect(50, 201, 100, 100);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(-1, 50, -100, 100);
+ ctx.fillStyle = 'brown';
+ ctx.fillRect(50, -1, 100, -100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html
new file mode 100644
index 0000000000..1823f78983
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.with-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.with-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur in="SourceGraphic" stdDeviation="30" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="201" y="50" width="100" height="100" fill="turquoise"/>
+ <rect x="50" y="201" width="100" height="100" fill="indigo"/>
+ <rect x="-101" y="50" width="100" height="100" fill="orange"/>
+ <rect x="50" y="-101" width="100" height="100" fill="brown"/>
+ </g>
+ </svg>`;
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping.html
new file mode 100644
index 0000000000..9e8161019a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.blur-from-outside-canvas.with-clipping.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.blur-from-outside-canvas.with-clipping-expected.html">
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.with-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.with-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [ {name: 'gaussianBlur', stdDeviation: 30} ]});
+
+ ctx.fillStyle = 'turquoise';
+ ctx.fillRect(201, 50, 100, 100);
+ ctx.fillStyle = 'indigo';
+ ctx.fillRect(50, 201, 100, 100);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(-1, 50, -100, 100);
+ ctx.fillStyle = 'brown';
+ ctx.fillRect(50, -1, 100, -100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full-expected.html
new file mode 100644
index 0000000000..5a47f8e118
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clearRect.full</title>
+<h1>2d.layer.clearRect.full</h1>
+<p class="desc">clearRect inside a layer can clear all of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full.html
new file mode 100644
index 0000000000..579c6e1053
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.full.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clearRect.full-expected.html">
+<title>Canvas test: 2d.layer.clearRect.full</title>
+<h1>2d.layer.clearRect.full</h1>
+<p class="desc">clearRect inside a layer can clear all of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.fillStyle = 'green';
+ ctx.clearRect(0, 0, 100, 100);
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial-expected.html
new file mode 100644
index 0000000000..ac75105cec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clearRect.partial</title>
+<h1>2d.layer.clearRect.partial</h1>
+<p class="desc">clearRect inside a layer can clear a portion of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 10);
+ ctx.fillRect(20, 60, 80, 10);
+ ctx.fillRect(20, 20, 10, 50);
+ ctx.fillRect(90, 20, 10, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial.html
new file mode 100644
index 0000000000..8323ffb931
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clearRect.partial.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clearRect.partial-expected.html">
+<title>Canvas test: 2d.layer.clearRect.partial</title>
+<h1>2d.layer.clearRect.partial</h1>
+<p class="desc">clearRect inside a layer can clear a portion of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.clearRect(30, 30, 60, 30);
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside-expected.html
new file mode 100644
index 0000000000..14e6d56245
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clip-inside-and-outside</title>
+<h1>2d.layer.clip-inside-and-outside</h1>
+<p class="desc">Check clipping set inside and outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginPath();
+ ctx2.rect(15, 15, 70, 70);
+ ctx2.clip();
+
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+
+ const canvas3 = new OffscreenCanvas(200, 200);
+ const ctx3 = canvas3.getContext('2d');
+
+ ctx3.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx3.drawImage(canvas2, 0, 0);
+ ctx3.endLayer();
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+ ctx.drawImage(canvas3, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside.html
new file mode 100644
index 0000000000..1a727bbd3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-and-outside.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clip-inside-and-outside-expected.html">
+<title>Canvas test: 2d.layer.clip-inside-and-outside</title>
+<h1>2d.layer.clip-inside-and-outside</h1>
+<p class="desc">Check clipping set inside and outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-expected.html
new file mode 100644
index 0000000000..281fc1d913
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside-expected.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clip-inside</title>
+<h1>2d.layer.clip-inside</h1>
+<p class="desc">Check clipping set inside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginPath();
+ ctx2.rect(15, 15, 70, 70);
+ ctx2.clip();
+
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx.drawImage(canvas2, 0, 0);
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside.html
new file mode 100644
index 0000000000..f3555c8321
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-inside.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clip-inside-expected.html">
+<title>Canvas test: 2d.layer.clip-inside</title>
+<h1>2d.layer.clip-inside</h1>
+<p class="desc">Check clipping set inside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside-expected.html
new file mode 100644
index 0000000000..1b18c2e8a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside-expected.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clip-outside</title>
+<h1>2d.layer.clip-outside</h1>
+<p class="desc">Check clipping set outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+ ctx2.endLayer();
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside.html
new file mode 100644
index 0000000000..bf8e84e3d2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.clip-outside.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clip-outside-expected.html">
+<title>Canvas test: 2d.layer.clip-outside</title>
+<h1>2d.layer.clip-outside</h1>
+<p class="desc">Check clipping set outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths-expected.html
new file mode 100644
index 0000000000..c394ecdfe3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.cross-layer-paths</title>
+<h1>2d.layer.cross-layer-paths</h1>
+<p class="desc">Checks that path defined in a layer is usable outside.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.moveTo(50, 0); ctx.lineTo(50, 100); ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths.html
new file mode 100644
index 0000000000..7feebfdce6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.cross-layer-paths.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.cross-layer-paths-expected.html">
+<title>Canvas test: 2d.layer.cross-layer-paths</title>
+<h1>2d.layer.cross-layer-paths</h1>
+<p class="desc">Checks that path defined in a layer is usable outside.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ ctx.translate(50, 0);
+ ctx.moveTo(0, 0);
+ ctx.endLayer();
+ ctx.lineTo(50, 100);
+ ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow-expected.html
new file mode 100644
index 0000000000..85503ae33a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow-expected.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.css-filters.blur-and-shadow</title>
+<h1>2d.layer.css-filters.blur-and-shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="5" />
+ <feDropShadow dx="10" dy="10" stdDeviation="5" flood-color="orange" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow.html
new file mode 100644
index 0000000000..08adfa3d74
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-and-shadow.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.css-filters.blur-and-shadow-expected.html">
+<title>Canvas test: 2d.layer.css-filters.blur-and-shadow</title>
+<h1>2d.layer.css-filters.blur-and-shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'blur(5px) drop-shadow(10px 10px 5px orange)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-expected.html
new file mode 100644
index 0000000000..c6131f6c1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.css-filters.blur</title>
+<h1>2d.layer.css-filters.blur</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="10" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur.html
new file mode 100644
index 0000000000..3eb3ab8f9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.blur.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.css-filters.blur-expected.html">
+<title>Canvas test: 2d.layer.css-filters.blur</title>
+<h1>2d.layer.css-filters.blur</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'blur(10px)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow-expected.html
new file mode 100644
index 0000000000..60f78d8096
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.css-filters.shadow</title>
+<h1>2d.layer.css-filters.shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx="-10" dy="-10" stdDeviation="5" flood-color="purple" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow.html
new file mode 100644
index 0000000000..e6df8a3ac2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.css-filters.shadow.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.css-filters.shadow-expected.html">
+<title>Canvas test: 2d.layer.css-filters.shadow</title>
+<h1>2d.layer.css-filters.shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'drop-shadow(-10px -10px 5px purple)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.exceptions-are-no-op.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.exceptions-are-no-op.html
new file mode 100644
index 0000000000..7ab2080fca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.exceptions-are-no-op.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.exceptions-are-no-op</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.exceptions-are-no-op</h1>
+<p class="desc">Checks that the context state is left unchanged if beginLayer throws.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Checks that the context state is left unchanged if beginLayer throws.");
+_addTest(function(canvas, ctx) {
+
+ // Get `beginLayer` to throw while parsing the filter.
+ assert_throws_js(TypeError,
+ () => ctx.beginLayer({filter: {name: 'colorMatrix',
+ values: 'foo'}}));
+ // `beginLayer` shouldn't have opened the layer, so `endLayer` should throw.
+ assert_throws_dom("InvalidStateError", () => ctx.endLayer());
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation-expected.html
new file mode 100644
index 0000000000..532c29576c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation-expected.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<title>Canvas test: 2d.layer.flush-on-frame-presentation</title>
+<h1>2d.layer.flush-on-frame-presentation</h1>
+<p class="desc">Check that layers state stack is flushed and rebuilt on frame renders.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script type="module">
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}});
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(40, 40, 75, 50);
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(50, 50, 75, 50);
+
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(70, 70, 75, 50);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(80, 80, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(80, 40, 75, 50);
+ document.documentElement.classList.remove("reftest-wait");
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation.html
new file mode 100644
index 0000000000..c8a118f8a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.flush-on-frame-presentation.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.flush-on-frame-presentation-expected.html">
+<title>Canvas test: 2d.layer.flush-on-frame-presentation</title>
+<h1>2d.layer.flush-on-frame-presentation</h1>
+<p class="desc">Check that layers state stack is flushed and rebuilt on frame renders.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script type="module">
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}});
+ ctx.fillRect(40, 40, 75, 50);
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(50, 50, 75, 50);
+
+ // Force a flush and restoration of the state stack:
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ ctx.fillRect(70, 70, 75, 50);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(80, 80, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(80, 40, 75, 50);
+ document.documentElement.classList.remove("reftest-wait");
+</script>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter-expected.html
new file mode 100644
index 0000000000..88057fc354
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter-expected.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-filter</title>
+<h1>2d.layer.global-filter</h1>
+<p class="desc">Tests that layers ignore the global context filter.</p>
+<canvas id="canvas" width="150" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(60, 10, 30, 30);
+ ctx.filter = 'blur(5px)'
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.fillRect(110, 10, 30, 30);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter.html
new file mode 100644
index 0000000000..cf46f41b97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-filter.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-filter-expected.html">
+<title>Canvas test: 2d.layer.global-filter</title>
+<h1>2d.layer.global-filter</h1>
+<p class="desc">Tests that layers ignore the global context filter.</p>
+<canvas id="canvas" width="150" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.filter = 'blur(5px)'
+
+ ctx.beginLayer();
+ ctx.fillRect(10, 10, 30, 30); // `ctx.filter` applied to draw call.
+ ctx.endLayer();
+
+ ctx.beginLayer();
+ ctx.filter = 'none';
+ ctx.fillRect(60, 10, 30, 30); // Should not be filted by the layer.
+ ctx.endLayer();
+
+ ctx.fillRect(110, 10, 30, 30); // `ctx.filter` is still set.
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha-expected.html
new file mode 100644
index 0000000000..0666e3098a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha</title>
+<h1>2d.layer.global-states.alpha</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending-expected.html
new file mode 100644
index 0000000000..8a45027588
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending-expected.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.blending</title>
+<h1>2d.layer.global-states.alpha.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.html
new file mode 100644
index 0000000000..8e15a2b936
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.blending</title>
+<h1>2d.layer.global-states.alpha.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow-expected.html
new file mode 100644
index 0000000000..f7b633b35f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow-expected.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow.html
new file mode 100644
index 0000000000..c8c6d433bc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.blending.shadow.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite-expected.html
new file mode 100644
index 0000000000..951049e638
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite-expected.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.composite</title>
+<h1>2d.layer.global-states.alpha.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.html
new file mode 100644
index 0000000000..1ac6a2cbfe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.composite</title>
+<h1>2d.layer.global-states.alpha.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow-expected.html
new file mode 100644
index 0000000000..0ae93871f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow-expected.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow.html
new file mode 100644
index 0000000000..92b8a0d7a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.composite.shadow.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.html
new file mode 100644
index 0000000000..829796acbf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha</title>
+<h1>2d.layer.global-states.alpha</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow-expected.html
new file mode 100644
index 0000000000..6f764c5001
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.shadow</title>
+<h1>2d.layer.global-states.alpha.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow.html
new file mode 100644
index 0000000000..a325302b3b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.alpha.shadow.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.shadow</title>
+<h1>2d.layer.global-states.alpha.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending-expected.html
new file mode 100644
index 0000000000..33fdf46a28
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.blending</title>
+<h1>2d.layer.global-states.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.html
new file mode 100644
index 0000000000..7d4d9ae4b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.blending</title>
+<h1>2d.layer.global-states.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow-expected.html
new file mode 100644
index 0000000000..6f969074f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.blending.shadow</title>
+<h1>2d.layer.global-states.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow.html
new file mode 100644
index 0000000000..51926d76d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.blending.shadow.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.blending.shadow</title>
+<h1>2d.layer.global-states.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite-expected.html
new file mode 100644
index 0000000000..ed7669c4cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.composite</title>
+<h1>2d.layer.global-states.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.html
new file mode 100644
index 0000000000..898d149924
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.composite</title>
+<h1>2d.layer.global-states.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow-expected.html
new file mode 100644
index 0000000000..b687c27f47
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.composite.shadow</title>
+<h1>2d.layer.global-states.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow.html
new file mode 100644
index 0000000000..c563a57b76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.composite.shadow.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.composite.shadow</title>
+<h1>2d.layer.global-states.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha-expected.html
new file mode 100644
index 0000000000..f304700feb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha</title>
+<h1>2d.layer.global-states.filter.alpha</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending-expected.html
new file mode 100644
index 0000000000..7c91ce4229
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending-expected.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title>
+<h1>2d.layer.global-states.filter.alpha.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html
new file mode 100644
index 0000000000..17e0f0c8c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title>
+<h1>2d.layer.global-states.filter.alpha.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html
new file mode 100644
index 0000000000..62942ffeae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow.html
new file mode 100644
index 0000000000..ccadfb624b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.shadow.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite-expected.html
new file mode 100644
index 0000000000..8e0d98648e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite-expected.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title>
+<h1>2d.layer.global-states.filter.alpha.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html
new file mode 100644
index 0000000000..71a27cf710
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title>
+<h1>2d.layer.global-states.filter.alpha.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html
new file mode 100644
index 0000000000..a649972546
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow.html
new file mode 100644
index 0000000000..b2907f02aa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.shadow.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html
new file mode 100644
index 0000000000..5133aa170e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha</title>
+<h1>2d.layer.global-states.filter.alpha</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow-expected.html
new file mode 100644
index 0000000000..169baee29b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow-expected.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html
new file mode 100644
index 0000000000..6aa8e75a95
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending-expected.html
new file mode 100644
index 0000000000..f81dcf72dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.blending</title>
+<h1>2d.layer.global-states.filter.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.html
new file mode 100644
index 0000000000..31628812c2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.blending</title>
+<h1>2d.layer.global-states.filter.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow-expected.html
new file mode 100644
index 0000000000..91f3725f8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow-expected.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.blending.shadow</title>
+<h1>2d.layer.global-states.filter.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow.html
new file mode 100644
index 0000000000..e54cf06d0d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.blending.shadow.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.blending.shadow</title>
+<h1>2d.layer.global-states.filter.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite-expected.html
new file mode 100644
index 0000000000..97e85a1593
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.composite</title>
+<h1>2d.layer.global-states.filter.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.html
new file mode 100644
index 0000000000..d7e365422f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.composite</title>
+<h1>2d.layer.global-states.filter.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow-expected.html
new file mode 100644
index 0000000000..4716bb2760
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow-expected.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.composite.shadow</title>
+<h1>2d.layer.global-states.filter.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow.html
new file mode 100644
index 0000000000..e5c7698634
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.composite.shadow</title>
+<h1>2d.layer.global-states.filter.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states-expected.html
new file mode 100644
index 0000000000..e56fe0b360
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.no-global-states</title>
+<h1>2d.layer.global-states.filter.no-global-states</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states.html
new file mode 100644
index 0000000000..68f4d5004a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.no-global-states.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.no-global-states-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.no-global-states</title>
+<h1>2d.layer.global-states.filter.no-global-states</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow-expected.html
new file mode 100644
index 0000000000..13ba2dd4cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow-expected.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.shadow</title>
+<h1>2d.layer.global-states.filter.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow.html
new file mode 100644
index 0000000000..9efcd9d4f7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.shadow.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.shadow</title>
+<h1>2d.layer.global-states.filter.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states-expected.html
new file mode 100644
index 0000000000..b91a2ae8b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.no-global-states</title>
+<h1>2d.layer.global-states.no-global-states</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states.html
new file mode 100644
index 0000000000..d561be2341
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.no-global-states.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.no-global-states-expected.html">
+<title>Canvas test: 2d.layer.global-states.no-global-states</title>
+<h1>2d.layer.global-states.no-global-states</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow-expected.html
new file mode 100644
index 0000000000..835e9d420a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.shadow</title>
+<h1>2d.layer.global-states.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow.html
new file mode 100644
index 0000000000..209316164c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.shadow.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.shadow</title>
+<h1>2d.layer.global-states.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html
new file mode 100644
index 0000000000..74e05e1e48
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.invalid-calls.beginLayer-reset-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.invalid-calls.beginLayer-reset-endLayer</h1>
+<p class="desc">Raises exception on beginLayer() + reset() + endLayer().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Raises exception on beginLayer() + reset() + endLayer().");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.reset();
+ ctx.endLayer();
+ });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-restore.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-restore.html
new file mode 100644
index 0000000000..1979cb6c73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-restore.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.invalid-calls.beginLayer-restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.invalid-calls.beginLayer-restore</h1>
+<p class="desc">Raises exception on beginLayer() + restore().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Raises exception on beginLayer() + restore().");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.restore();
+ });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html
new file mode 100644
index 0000000000..c635ac75b9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.invalid-calls.beginLayer-save-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.invalid-calls.beginLayer-save-endLayer</h1>
+<p class="desc">Raises exception on beginLayer() + save() + endLayer().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Raises exception on beginLayer() + save() + endLayer().");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.save();
+ ctx.endLayer();
+ });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.endLayer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.endLayer.html
new file mode 100644
index 0000000000..c39a352d65
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.endLayer.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.invalid-calls.endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.invalid-calls.endLayer</h1>
+<p class="desc">Raises exception on lone endLayer calls.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Raises exception on lone endLayer calls.");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.endLayer();
+ });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-beginLayer-restore.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-beginLayer-restore.html
new file mode 100644
index 0000000000..e2d4d56589
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-beginLayer-restore.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.invalid-calls.save-beginLayer-restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.invalid-calls.save-beginLayer-restore</h1>
+<p class="desc">Raises exception on save() + beginLayer() + restore().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Raises exception on save() + beginLayer() + restore().");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.save();
+ ctx.beginLayer();
+ ctx.restore();
+ });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-endLayer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-endLayer.html
new file mode 100644
index 0000000000..f4308e1191
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.invalid-calls.save-endLayer.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.invalid-calls.save-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.invalid-calls.save-endLayer</h1>
+<p class="desc">Raises exception on save() + endLayer().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Raises exception on save() + endLayer().");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.save();
+ ctx.endLayer();
+ });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.layer-rendering-state-reset-in-layer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.layer-rendering-state-reset-in-layer.html
new file mode 100644
index 0000000000..9283fd39b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.layer-rendering-state-reset-in-layer.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.layer-rendering-state-reset-in-layer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.layer-rendering-state-reset-in-layer</h1>
+<p class="desc">Tests that layers ignore the global context filter.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Tests that layers ignore the global context filter.");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalAlpha = 0.5;
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#0000ff';
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 20;
+ ctx.shadowBlur = 30;
+
+ _assertSame(ctx.globalAlpha, 0.5, "ctx.globalAlpha", "0.5");
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ _assertSame(ctx.shadowColor, '#0000ff', "ctx.shadowColor", "'#0000ff'");
+ _assertSame(ctx.shadowOffsetX, 10, "ctx.shadowOffsetX", "10");
+ _assertSame(ctx.shadowOffsetY, 20, "ctx.shadowOffsetY", "20");
+ _assertSame(ctx.shadowBlur, 30, "ctx.shadowBlur", "30");
+
+ ctx.beginLayer();
+
+ _assertSame(ctx.globalAlpha, 1.0, "ctx.globalAlpha", "1.0");
+ _assertSame(ctx.globalCompositeOperation, 'source-over', "ctx.globalCompositeOperation", "'source-over'");
+ _assertSame(ctx.shadowColor, 'rgba(0, 0, 0, 0)', "ctx.shadowColor", "'rgba(0, 0, 0, 0)'");
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+
+ ctx.endLayer();
+
+ _assertSame(ctx.globalAlpha, 0.5, "ctx.globalAlpha", "0.5");
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ _assertSame(ctx.shadowColor, '#0000ff', "ctx.shadowColor", "'#0000ff'");
+ _assertSame(ctx.shadowOffsetX, 10, "ctx.shadowOffsetX", "10");
+ _assertSame(ctx.shadowOffsetY, 20, "ctx.shadowOffsetY", "20");
+ _assertSame(ctx.shadowBlur, 30, "ctx.shadowBlur", "30");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html
new file mode 100644
index 0000000000..f1204aa61b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.malformed-operations-with-promises.createImageBitmap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.malformed-operations-with-promises.createImageBitmap</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ await createImageBitmap(canvas);
+ // Make sure the exception isn't caused by calling the function twice.
+ await createImageBitmap(canvas);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ await promise_rejects_dom(t, 'InvalidStateError', createImageBitmap(canvas));
+
+}, "Check that exceptions are thrown for operations that are malformed while layers are open.");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.toBlob.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.toBlob.html
new file mode 100644
index 0000000000..6c69bb3784
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations-with-promises.toBlob.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.malformed-operations-with-promises.toBlob</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.malformed-operations-with-promises.toBlob</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ await new Promise(resolve => canvas.toBlob(resolve));
+ // Make sure the exception isn't caused by calling the function twice.
+ await new Promise(resolve => canvas.toBlob(resolve));
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ await promise_rejects_dom(t, 'InvalidStateError', new Promise(resolve => canvas.toBlob(resolve)));
+
+}, "Check that exceptions are thrown for operations that are malformed while layers are open.");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.createPattern.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.createPattern.html
new file mode 100644
index 0000000000..f927b96524
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.createPattern.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.malformed-operations.createPattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.malformed-operations.createPattern</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+_addTest(function(canvas, ctx) {
+
+ // Shouldn't throw on its own.
+ ctx.createPattern(canvas, 'repeat');
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.createPattern(canvas, 'repeat');
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.createPattern(canvas, 'repeat'));
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.drawImage.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.drawImage.html
new file mode 100644
index 0000000000..8bcc89d38e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.drawImage.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.malformed-operations.drawImage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.malformed-operations.drawImage</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+_addTest(function(canvas, ctx) {
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+ // Shouldn't throw on its own.
+ ctx2.drawImage(canvas, 0, 0);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx2.drawImage(canvas, 0, 0);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx2.drawImage(canvas, 0, 0));
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.getImageData.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.getImageData.html
new file mode 100644
index 0000000000..5dc3fcc017
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.getImageData.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.malformed-operations.getImageData</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.malformed-operations.getImageData</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+_addTest(function(canvas, ctx) {
+
+ // Shouldn't throw on its own.
+ ctx.getImageData(0, 0, 200, 200);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.getImageData(0, 0, 200, 200);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.getImageData(0, 0, 200, 200));
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.putImageData.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.putImageData.html
new file mode 100644
index 0000000000..fd4fc262c2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.putImageData.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.malformed-operations.putImageData</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.malformed-operations.putImageData</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+_addTest(function(canvas, ctx) {
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d')
+ const data = ctx2.getImageData(0, 0, 1, 1);
+ // Shouldn't throw on its own.
+ ctx.putImageData(data, 0, 0);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.putImageData(data, 0, 0);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.putImageData(data, 0, 0));
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.toDataURL.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.toDataURL.html
new file mode 100644
index 0000000000..c9bb4f3875
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.malformed-operations.toDataURL.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.malformed-operations.toDataURL</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.malformed-operations.toDataURL</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="200" height="200"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+_addTest(function(canvas, ctx) {
+
+ // Shouldn't throw on its own.
+ canvas.toDataURL();
+ // Make sure the exception isn't caused by calling the function twice.
+ canvas.toDataURL();
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => canvas.toDataURL());
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-expected.html
new file mode 100644
index 0000000000..65525d4d6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-expected.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.nested</title>
+<h1>2d.layer.nested</h1>
+<p class="desc">Tests nested canvas layers.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 40, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx2.fillRect(60, 60, 75, 50);
+
+ ctx2.globalAlpha = 0.5;
+
+ canvas3 = document.createElement("canvas");
+ ctx3 = canvas3.getContext("2d");
+
+ ctx3.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx3.fillRect(50, 50, 75, 50);
+ ctx3.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx3.fillRect(70, 70, 75, 50);
+
+ ctx2.drawImage(canvas3, 0, 0);
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters-expected.html
new file mode 100644
index 0000000000..8b53e2dc76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters-expected.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.nested-filters</title>
+<h1>2d.layer.nested-filters</h1>
+<p class="desc">Checks that nested layers work properly when both apply filters.</p>
+<canvas id="canvas" width="400" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(20, 20, 100, 100);
+ ctx.fillRect(30, 30, 100, 100);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(40, 40, 100, 100);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(280, 80, 100, 100);
+ ctx.fillRect(270, 70, 100, 100);
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(260, 60, 100, 100);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(250, 50, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters.html
new file mode 100644
index 0000000000..333de67ac9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested-filters.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.nested-filters-expected.html">
+<title>Canvas test: 2d.layer.nested-filters</title>
+<h1>2d.layer.nested-filters</h1>
+<p class="desc">Checks that nested layers work properly when both apply filters.</p>
+<canvas id="canvas" width="400" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -20, dy: -20,
+ stdDeviation: 0, floodColor: 'yellow'}});
+ ctx.beginLayer({filter: 'drop-shadow(-10px -10px 0 blue)'});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ ctx.beginLayer({filter: 'drop-shadow(20px 20px 0 blue)'});
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: 10, dy: 10,
+ stdDeviation: 0, floodColor: 'yellow'}});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(250, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested.html
new file mode 100644
index 0000000000..a508d8e5c8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.nested.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.nested-expected.html">
+<title>Canvas test: 2d.layer.nested</title>
+<h1>2d.layer.nested</h1>
+<p class="desc">Tests nested canvas layers.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 40, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas-expected.html
new file mode 100644
index 0000000000..89c85de1e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.opaque-canvas</title>
+<h1>2d.layer.opaque-canvas</h1>
+<p class="desc">Checks that layer blending works inside opaque canvas</p>
+<canvas id="canvas" width="300" height="300">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 300, 300);
+
+ ctx.fillStyle = 'black';
+ ctx.fillRect(0, 0, 200, 200);
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(10, 10, 100, 100);
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = 'green';
+ ctx2.fillRect(50, 50, 100, 100);
+ ctx2.globalAlpha = 0.8;
+ ctx2.fillStyle = 'yellow';
+ ctx2.fillRect(75, 25, 100, 100);
+
+ ctx.shadowColor = 'rgba(200, 100, 50, 0.5)';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas.html
new file mode 100644
index 0000000000..be8b088fbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.opaque-canvas.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.opaque-canvas-expected.html">
+<title>Canvas test: 2d.layer.opaque-canvas</title>
+<h1>2d.layer.opaque-canvas</h1>
+<p class="desc">Checks that layer blending works inside opaque canvas</p>
+<canvas id="canvas" width="300" height="300">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = document.createElement('canvas');
+ canvas2.width = 200;
+ canvas2.height = 200;
+ const ctx2 = canvas2.getContext('2d', {alpha: false});
+
+ ctx2.fillStyle = 'purple';
+ ctx2.fillRect(10, 10, 100, 100);
+
+ ctx2.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: 10,
+ stdDeviation: 0,
+ floodColor: 'rgba(200, 100, 50, 0.5)'}});
+ ctx2.fillStyle = 'green';
+ ctx2.fillRect(50, 50, 100, 100);
+ ctx2.globalAlpha = 0.8;
+ ctx2.fillStyle = 'yellow';
+ ctx2.fillRect(75, 25, 100, 100);
+ ctx2.endLayer();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 300, 300);
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset-expected.html
new file mode 100644
index 0000000000..93131dca9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.reset</title>
+<h1>2d.layer.reset</h1>
+<p class="desc">Checks that reset discards any pending layers.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(10, 10, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset.html
new file mode 100644
index 0000000000..9ad779abfd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.reset.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.reset-expected.html">
+<title>Canvas test: 2d.layer.reset</title>
+<h1>2d.layer.reset</h1>
+<p class="desc">Checks that reset discards any pending layers.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ // Global states:
+ ctx.globalAlpha = 0.3;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -3;
+ ctx.shadowOffsetY = 3;
+ ctx.shadowColor = 'rgba(0, 30, 0, 0.3)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -3, dy: 3}});
+
+ // Layer states:
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -6;
+ ctx.shadowOffsetY = 6;
+ ctx.shadowColor = 'rgba(0, 60, 0, 0.6)';
+ ctx.shadowBlur = 3;
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style-expected.html
new file mode 100644
index 0000000000..1d0ac3558d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style-expected.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.restore-style</title>
+<h1>2d.layer.restore-style</h1>
+<p class="desc">Test that ensure layers restores style values upon endLayer.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(60, 60, 75, 50);
+ ctx.drawImage(canvas2, 0, 0);
+
+ ctx.fillRect(70, 70, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style.html
new file mode 100644
index 0000000000..2537f409d6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.restore-style.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.restore-style-expected.html">
+<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-950">
+<title>Canvas test: 2d.layer.restore-style</title>
+<h1>2d.layer.restore-style</h1>
+<p class="desc">Test that ensure layers restores style values upon endLayer.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0,0,255,1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(70, 70, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex-expected.html
new file mode 100644
index 0000000000..ef46f69e2a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.several-complex</title>
+<h1>2d.layer.several-complex</h1>
+<p class="desc">Test to ensure beginlayer works for filter, alpha and shadow, even with consecutive layers.</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 95, 70);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'orange';
+ ctx.shadowBlur = 3;
+
+ var canvas2 = [5];
+ var ctx2 = [5];
+
+ for (let i = 0; i < 5; i++) {
+ canvas2[i] = document.createElement("canvas");
+ ctx2[i] = canvas2[i].getContext("2d");
+ ctx2[i].fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2[i].fillRect(60, 40, 75, 50);
+ ctx2[i].fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2[i].fillRect(80, 60, 75, 50);
+
+ ctx.drawImage(canvas2[i], i, i);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex.html
new file mode 100644
index 0000000000..cff0c123ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.several-complex.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.several-complex-expected.html">
+<meta name=fuzzy content="maxDifference=0-3; totalPixels=0-6318">
+<title>Canvas test: 2d.layer.several-complex</title>
+<h1>2d.layer.several-complex</h1>
+<p class="desc">Test to ensure beginlayer works for filter, alpha and shadow, even with consecutive layers.</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 95, 70);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'orange';
+ ctx.shadowBlur = 3
+
+ for (let i = 0; i < 5; i++) {
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60 + i, 40 + i, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(80 + i, 60 + i, 75, 50);
+
+ ctx.endLayer();
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html
new file mode 100644
index 0000000000..cc10684a9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ // No clipping.
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html
new file mode 100644
index 0000000000..377dd55ef6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html
new file mode 100644
index 0000000000..88a3a67c7b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance.html
new file mode 100644
index 0000000000..8ade08bec5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.long-distance-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html
new file mode 100644
index 0000000000..8980708dd1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ // No clipping.
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html
new file mode 100644
index 0000000000..024fc8c9a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html
new file mode 100644
index 0000000000..7ced448144
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance.html
new file mode 100644
index 0000000000..37398400d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.short-distance.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.short-distance-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-endLayer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-endLayer.html
new file mode 100644
index 0000000000..609cb19a7d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-endLayer.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.beginLayer-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.beginLayer-endLayer</h1>
+<p class="desc">No exception raised on beginLayer() + endLayer().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on beginLayer() + endLayer().");
+_addTest(function(canvas, ctx) {
+
+ ctx.beginLayer();
+ ctx.save();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-save.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-save.html
new file mode 100644
index 0000000000..9658040296
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer-save.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.beginLayer-save</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.beginLayer-save</h1>
+<p class="desc">No exception raised on beginLayer() + save().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on beginLayer() + save().");
+_addTest(function(canvas, ctx) {
+
+ ctx.beginLayer();
+ ctx.save();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer.html
new file mode 100644
index 0000000000..0556683331
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.beginLayer.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.beginLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.beginLayer</h1>
+<p class="desc">No exception raised on lone beginLayer() calls.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on lone beginLayer() calls.");
+_addTest(function(canvas, ctx) {
+
+ ctx.beginLayer();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.restore.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.restore.html
new file mode 100644
index 0000000000..b7a370306f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.restore.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.restore</h1>
+<p class="desc">No exception raised on lone restore() calls.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on lone restore() calls.");
+_addTest(function(canvas, ctx) {
+
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save-beginLayer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save-beginLayer.html
new file mode 100644
index 0000000000..816398c7fc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save-beginLayer.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.save-beginLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.save-beginLayer</h1>
+<p class="desc">No exception raised on save() + beginLayer().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on save() + beginLayer().");
+_addTest(function(canvas, ctx) {
+
+ ctx.save();
+ ctx.beginLayer();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save.html
new file mode 100644
index 0000000000..d8df8cedce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.save</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.save</h1>
+<p class="desc">No exception raised on lone save() calls.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on lone save() calls.");
+_addTest(function(canvas, ctx) {
+
+ ctx.save();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_reset_restore.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_reset_restore.html
new file mode 100644
index 0000000000..4c733263a6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_reset_restore.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.save_reset_restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.save_reset_restore</h1>
+<p class="desc">No exception raised on save() + reset() + restore().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on save() + reset() + restore().");
+_addTest(function(canvas, ctx) {
+
+ ctx.save();
+ ctx.reset();
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_restore.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_restore.html
new file mode 100644
index 0000000000..27ae70278e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.valid-calls.save_restore.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.valid-calls.save_restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.layer.valid-calls.save_restore</h1>
+<p class="desc">No exception raised on save() + restore().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("No exception raised on save() + restore().");
+_addTest(function(canvas, ctx) {
+
+ ctx.save();
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.butt.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.butt.html
new file mode 100644
index 0000000000..f8c7cab1f2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.butt.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cap.butt</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cap.butt</h1>
+<p class="desc">lineCap 'butt' is rendered correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineCap 'butt' is rendered correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'butt';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 25,14, 0,255,0,255);
+ _assertPixel(canvas, 25,15, 0,255,0,255);
+ _assertPixel(canvas, 25,16, 0,255,0,255);
+ _assertPixel(canvas, 25,34, 0,255,0,255);
+ _assertPixel(canvas, 25,35, 0,255,0,255);
+ _assertPixel(canvas, 25,36, 0,255,0,255);
+
+ _assertPixel(canvas, 75,14, 0,255,0,255);
+ _assertPixel(canvas, 75,15, 0,255,0,255);
+ _assertPixel(canvas, 75,16, 0,255,0,255);
+ _assertPixel(canvas, 75,34, 0,255,0,255);
+ _assertPixel(canvas, 75,35, 0,255,0,255);
+ _assertPixel(canvas, 75,36, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.closed.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.closed.html
new file mode 100644
index 0000000000..263c6c6c76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.closed.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cap.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cap.closed</h1>
+<p class="desc">Line caps are not drawn at the corners of an unclosed rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Line caps are not drawn at the corners of an unclosed rectangle");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.invalid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.invalid.html
new file mode 100644
index 0000000000..22e98ee326
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.invalid.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cap.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cap.invalid</h1>
+<p class="desc">Setting lineCap to invalid values is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting lineCap to invalid values is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineCap = 'butt'
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'invalid';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'ROUND';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round\0';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round ';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = "";
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'bevel';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.open.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.open.html
new file mode 100644
index 0000000000..6f7918a1c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.open.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cap.open</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cap.open</h1>
+<p class="desc">Line caps are drawn at the corners of an unclosed rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Line caps are drawn at the corners of an unclosed rectangle");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.lineTo(200, 200);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.round.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.round.html
new file mode 100644
index 0000000000..3990ad384e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.round.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cap.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cap.round</h1>
+<p class="desc">lineCap 'round' is rendered correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineCap 'round' is rendered correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineCap = 'round';
+ ctx.lineWidth = 20;
+
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(35-tol, 15);
+ ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
+ ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(85+tol, 15);
+ ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
+ ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
+ ctx.fill();
+
+ _assertPixel(canvas, 17,6, 0,255,0,255);
+ _assertPixel(canvas, 25,6, 0,255,0,255);
+ _assertPixel(canvas, 32,6, 0,255,0,255);
+ _assertPixel(canvas, 17,43, 0,255,0,255);
+ _assertPixel(canvas, 25,43, 0,255,0,255);
+ _assertPixel(canvas, 32,43, 0,255,0,255);
+
+ _assertPixel(canvas, 67,6, 0,255,0,255);
+ _assertPixel(canvas, 75,6, 0,255,0,255);
+ _assertPixel(canvas, 82,6, 0,255,0,255);
+ _assertPixel(canvas, 67,43, 0,255,0,255);
+ _assertPixel(canvas, 75,43, 0,255,0,255);
+ _assertPixel(canvas, 82,43, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.square.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.square.html
new file mode 100644
index 0000000000..8d6af320fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.square.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cap.square</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cap.square</h1>
+<p class="desc">lineCap 'square' is rendered correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineCap 'square' is rendered correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 5, 20, 40);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 5, 20, 40);
+
+ _assertPixel(canvas, 25,4, 0,255,0,255);
+ _assertPixel(canvas, 25,5, 0,255,0,255);
+ _assertPixel(canvas, 25,6, 0,255,0,255);
+ _assertPixel(canvas, 25,44, 0,255,0,255);
+ _assertPixel(canvas, 25,45, 0,255,0,255);
+ _assertPixel(canvas, 25,46, 0,255,0,255);
+
+ _assertPixel(canvas, 75,4, 0,255,0,255);
+ _assertPixel(canvas, 75,5, 0,255,0,255);
+ _assertPixel(canvas, 75,6, 0,255,0,255);
+ _assertPixel(canvas, 75,44, 0,255,0,255);
+ _assertPixel(canvas, 75,45, 0,255,0,255);
+ _assertPixel(canvas, 75,46, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.valid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.valid.html
new file mode 100644
index 0000000000..a11d32030e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cap.valid.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cap.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cap.valid</h1>
+<p class="desc">Setting lineCap to valid values works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting lineCap to valid values works");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineCap = 'butt'
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'round';
+ _assertSame(ctx.lineCap, 'round', "ctx.lineCap", "'round'");
+
+ ctx.lineCap = 'square';
+ _assertSame(ctx.lineCap, 'square', "ctx.lineCap", "'square'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cross.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cross.html
new file mode 100644
index 0000000000..e6866e3e40
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.cross.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.cross</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.cross</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(110, 50);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(100, 60);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.defaults.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.defaults.html
new file mode 100644
index 0000000000..daa4634387
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.defaults.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.defaults</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.defaults</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+ _assertSame(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'");
+ _assertSame(ctx.miterLimit, 10, "ctx.miterLimit", "10");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.fill.noop.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.fill.noop.html
new file mode 100644
index 0000000000..6dd8804ab0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.fill.noop.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.fill.noop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.fill.noop</h1>
+<p class="desc">Filling a line draws nothing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Filling a line draws nothing");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 20;
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(90, 30);
+ ctx.fill();
+ _assertPixel(canvas, 50,24, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,26, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.invalid.strokestyle.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.invalid.strokestyle.html
new file mode 100644
index 0000000000..89a234ecc3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.invalid.strokestyle.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.invalid.strokestyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.invalid.strokestyle</h1>
+<p class="desc">Verify correct behavior of canvas on an invalid strokeStyle()</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify correct behavior of canvas on an invalid strokeStyle()");
+_addTest(function(canvas, ctx) {
+
+ ctx.strokeStyle = 'rgb(0, 255, 0)';
+ ctx.strokeStyle = 'nonsense';
+ ctx.lineWidth = 200;
+ ctx.moveTo(0,100);
+ ctx.lineTo(200,100);
+ ctx.stroke();
+ var imageData = ctx.getImageData(0, 0, 200, 200);
+ var imgdata = imageData.data;
+ _assert(imgdata[4] == 0, "imgdata[\""+(4)+"\"] == 0");
+ _assert(imgdata[5] == 255, "imgdata[\""+(5)+"\"] == 255");
+ _assert(imgdata[6] == 0, "imgdata[\""+(6)+"\"] == 0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.bevel.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.bevel.html
new file mode 100644
index 0000000000..041e9a1605
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.bevel.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.bevel</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.bevel</h1>
+<p class="desc">lineJoin 'bevel' is rendered correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineJoin 'bevel' is rendered correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.lineTo(40-tol, 20);
+ ctx.lineTo(30, 10+tol);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.lineTo(90+tol, 20);
+ ctx.lineTo(80, 10-tol);
+ ctx.fill();
+
+ _assertPixel(canvas, 34,16, 0,255,0,255);
+ _assertPixel(canvas, 34,15, 0,255,0,255);
+ _assertPixel(canvas, 35,15, 0,255,0,255);
+ _assertPixel(canvas, 36,15, 0,255,0,255);
+ _assertPixel(canvas, 36,14, 0,255,0,255);
+
+ _assertPixel(canvas, 84,16, 0,255,0,255);
+ _assertPixel(canvas, 84,15, 0,255,0,255);
+ _assertPixel(canvas, 85,15, 0,255,0,255);
+ _assertPixel(canvas, 86,15, 0,255,0,255);
+ _assertPixel(canvas, 86,14, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.closed.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.closed.html
new file mode 100644
index 0000000000..a52219ccce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.closed.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.closed</h1>
+<p class="desc">Line joins are drawn at the corner of a closed rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Line joins are drawn at the corner of a closed rectangle");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.invalid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.invalid.html
new file mode 100644
index 0000000000..3c34ef3475
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.invalid.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.invalid</h1>
+<p class="desc">Setting lineJoin to invalid values is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting lineJoin to invalid values is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineJoin = 'bevel'
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'invalid';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'ROUND';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round\0';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round ';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = "";
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'butt';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.miter.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.miter.html
new file mode 100644
index 0000000000..5a3472e92d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.miter.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.miter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.miter</h1>
+<p class="desc">lineJoin 'miter' is rendered correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineJoin 'miter' is rendered correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 30, 20);
+ ctx.fillRect(20, 10, 20, 30);
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 30, 20);
+ ctx.fillRect(70, 10, 20, 30);
+
+ _assertPixel(canvas, 38,12, 0,255,0,255);
+ _assertPixel(canvas, 39,11, 0,255,0,255);
+ _assertPixel(canvas, 40,10, 0,255,0,255);
+ _assertPixel(canvas, 41,9, 0,255,0,255);
+ _assertPixel(canvas, 42,8, 0,255,0,255);
+
+ _assertPixel(canvas, 88,12, 0,255,0,255);
+ _assertPixel(canvas, 89,11, 0,255,0,255);
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 91,9, 0,255,0,255);
+ _assertPixel(canvas, 92,8, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.open.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.open.html
new file mode 100644
index 0000000000..55b7a8b49e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.open.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.open</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.open</h1>
+<p class="desc">Line joins are not drawn at the corner of an unclosed rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Line joins are not drawn at the corner of an unclosed rectangle");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.parallel.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.parallel.html
new file mode 100644
index 0000000000..cd736b503d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.parallel.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.parallel</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.parallel</h1>
+<p class="desc">Line joins are drawn at 180-degree joins</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Line joins are drawn at 180-degree joins");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 300;
+ ctx.lineJoin = 'round';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(-100, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.round.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.round.html
new file mode 100644
index 0000000000..fb968b9966
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.round.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.round</h1>
+<p class="desc">lineJoin 'round' is rendered correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineJoin 'round' is rendered correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'round';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ _assertPixel(canvas, 36,14, 0,255,0,255);
+ _assertPixel(canvas, 36,13, 0,255,0,255);
+ _assertPixel(canvas, 37,13, 0,255,0,255);
+ _assertPixel(canvas, 38,13, 0,255,0,255);
+ _assertPixel(canvas, 38,12, 0,255,0,255);
+
+ _assertPixel(canvas, 86,14, 0,255,0,255);
+ _assertPixel(canvas, 86,13, 0,255,0,255);
+ _assertPixel(canvas, 87,13, 0,255,0,255);
+ _assertPixel(canvas, 88,13, 0,255,0,255);
+ _assertPixel(canvas, 88,12, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.valid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.valid.html
new file mode 100644
index 0000000000..3e5e200cb5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.join.valid.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.join.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.join.valid</h1>
+<p class="desc">Setting lineJoin to valid values works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting lineJoin to valid values works");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineJoin = 'bevel'
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'round';
+ _assertSame(ctx.lineJoin, 'round', "ctx.lineJoin", "'round'");
+
+ ctx.lineJoin = 'miter';
+ _assertSame(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.acute.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.acute.html
new file mode 100644
index 0000000000..6acba4f3d2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.acute.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.acute</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.acute</h1>
+<p class="desc">Miter joins are drawn correctly with acute angles</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Miter joins are drawn correctly with acute angles");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 2.614;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 2.613;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.exceeded.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.exceeded.html
new file mode 100644
index 0000000000..542851d580
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.exceeded.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.exceeded</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.exceeded</h1>
+<p class="desc">Miter joins are not drawn when the miter limit is exceeded</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.invalid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.invalid.html
new file mode 100644
index 0000000000..826a6e24a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.invalid.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.invalid</h1>
+<p class="desc">Setting miterLimit to invalid values is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting miterLimit to invalid values is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.miterLimit = 1.5;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 0;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -1;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = Infinity;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -Infinity;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = NaN;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 'string';
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = true;
+ _assertSame(ctx.miterLimit, 1, "ctx.miterLimit", "1");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = false;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.lineedge.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.lineedge.html
new file mode 100644
index 0000000000..68eeb06162
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.lineedge.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.lineedge</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.lineedge</h1>
+<p class="desc">Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.strokeRect(100, 25, 200, 0);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.obtuse.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.obtuse.html
new file mode 100644
index 0000000000..2dd08f6afc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.obtuse.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.obtuse</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.obtuse</h1>
+<p class="desc">Miter joins are drawn correctly with obtuse angles</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Miter joins are drawn correctly with obtuse angles");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 1600;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.083;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.082;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.rightangle.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.rightangle.html
new file mode 100644
index 0000000000..7ae9f5e232
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.rightangle.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.rightangle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.rightangle</h1>
+<p class="desc">Miter joins are not drawn when the miter limit is exceeded, on exact right angles</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded, on exact right angles");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 200);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.valid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.valid.html
new file mode 100644
index 0000000000..51b00c292d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.valid.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.valid</h1>
+<p class="desc">Setting miterLimit to valid values works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting miterLimit to valid values works");
+_addTest(function(canvas, ctx) {
+
+ ctx.miterLimit = 1.5;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = "1e1";
+ _assertSame(ctx.miterLimit, 10, "ctx.miterLimit", "10");
+
+ ctx.miterLimit = 1/1024;
+ _assertSame(ctx.miterLimit, 1/1024, "ctx.miterLimit", "1/1024");
+
+ ctx.miterLimit = 1000;
+ _assertSame(ctx.miterLimit, 1000, "ctx.miterLimit", "1000");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.within.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.within.html
new file mode 100644
index 0000000000..f438866009
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.miter.within.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.miter.within</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.miter.within</h1>
+<p class="desc">Miter joins are drawn when the miter limit is not quite exceeded</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Miter joins are drawn when the miter limit is not quite exceeded");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.416;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.union.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.union.html
new file mode 100644
index 0000000000..9d43cebee7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.union.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.union</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.union</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 24);
+ ctx.lineTo(100, 25);
+ ctx.lineTo(0, 26);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 25,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 25,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.basic.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.basic.html
new file mode 100644
index 0000000000..f2e9a9f86d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.basic.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.width.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.width.basic</h1>
+<p class="desc">lineWidth determines the width of line strokes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineWidth determines the width of line strokes");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 20;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 14,25, 0,255,0,255);
+ _assertPixel(canvas, 15,25, 0,255,0,255);
+ _assertPixel(canvas, 16,25, 0,255,0,255);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 34,25, 0,255,0,255);
+ _assertPixel(canvas, 35,25, 0,255,0,255);
+ _assertPixel(canvas, 36,25, 0,255,0,255);
+
+ _assertPixel(canvas, 64,25, 0,255,0,255);
+ _assertPixel(canvas, 65,25, 0,255,0,255);
+ _assertPixel(canvas, 66,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 84,25, 0,255,0,255);
+ _assertPixel(canvas, 85,25, 0,255,0,255);
+ _assertPixel(canvas, 86,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.invalid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.invalid.html
new file mode 100644
index 0000000000..363060cf6d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.invalid.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.width.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.width.invalid</h1>
+<p class="desc">Setting lineWidth to invalid values is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting lineWidth to invalid values is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineWidth = 1.5;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 0;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -1;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = Infinity;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -Infinity;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = NaN;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 'string';
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = true;
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = false;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.scaledefault.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.scaledefault.html
new file mode 100644
index 0000000000..6c4ec52b5d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.scaledefault.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.width.scaledefault</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.width.scaledefault</h1>
+<p class="desc">Default lineWidth strokes are affected by scale transformations</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Default lineWidth strokes are affected by scale transformations");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(50, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.moveTo(0, 0.5);
+ ctx.lineTo(2, 0.5);
+ ctx.stroke();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 50,5, 0,255,0,255);
+ _assertPixel(canvas, 50,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.transformed.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.transformed.html
new file mode 100644
index 0000000000..600ce93fb7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.transformed.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.width.transformed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.width.transformed</h1>
+<p class="desc">Line stroke widths are affected by scale transformations</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Line stroke widths are affected by scale transformations");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 4;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.save();
+ ctx.scale(5, 1);
+ ctx.beginPath();
+ ctx.moveTo(5, 15);
+ ctx.lineTo(5, 35);
+ ctx.stroke();
+ ctx.restore();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.save();
+ ctx.scale(-5, 1);
+ ctx.beginPath();
+ ctx.moveTo(-15, 15);
+ ctx.lineTo(-15, 35);
+ ctx.stroke();
+ ctx.restore();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 14,25, 0,255,0,255);
+ _assertPixel(canvas, 15,25, 0,255,0,255);
+ _assertPixel(canvas, 16,25, 0,255,0,255);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 34,25, 0,255,0,255);
+ _assertPixel(canvas, 35,25, 0,255,0,255);
+ _assertPixel(canvas, 36,25, 0,255,0,255);
+
+ _assertPixel(canvas, 64,25, 0,255,0,255);
+ _assertPixel(canvas, 65,25, 0,255,0,255);
+ _assertPixel(canvas, 66,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 84,25, 0,255,0,255);
+ _assertPixel(canvas, 85,25, 0,255,0,255);
+ _assertPixel(canvas, 86,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.valid.html b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.valid.html
new file mode 100644
index 0000000000..1a76b0ed4c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/line-styles/2d.line.width.valid.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.line.width.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.line.width.valid</h1>
+<p class="desc">Setting lineWidth to valid values works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting lineWidth to valid values works");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineWidth = 1.5;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = "1e1";
+ _assertSame(ctx.lineWidth, 10, "ctx.lineWidth", "10");
+
+ ctx.lineWidth = 1/1024;
+ _assertSame(ctx.lineWidth, 1/1024, "ctx.lineWidth", "1/1024");
+
+ ctx.lineWidth = 1000;
+ _assertSame(ctx.lineWidth, 1000, "ctx.lineWidth", "1000");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/manual/README.md b/testing/web-platform/tests/html/canvas/element/manual/README.md
new file mode 100644
index 0000000000..68d877200b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/README.md
@@ -0,0 +1 @@
+This folder contains tests that were manually added to the repository. All other tests have been autogenerated by html/canvas/tools/build.sh \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001-ref.htm
new file mode 100644
index 0000000000..31ddfcafd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001-ref.htm
@@ -0,0 +1,22 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: arcTo() adds to subpath if same point</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+ ctx.moveTo(0, 50);
+
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: If x1,y1 and x2,y2 are the same point, then arcTo must add x1,y1 to the subpath, and connect that point to x0,y0 with a straight line.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas (test ref).</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001.htm b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001.htm
new file mode 100644
index 0000000000..c3f2fb6f43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001.htm
@@ -0,0 +1,26 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: arcTo() adds to subpath if same point</title>
+ <link rel="match" href="canvas_complexshapes_arcto_001-ref.htm">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto" />
+ <meta name="assert" content="If x1,y1 and x2,y2 are the same point, then arcTo must add x1,y1 to the subpath, and connect that point to x0,y0 with a straight line." />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+ ctx.moveTo(0, 50);
+
+ // Since (x1, y1) and (x2, y2) are the same point, (x1, y1) must be added to the subpath, thus creating a line.
+ ctx.arcTo(100, 50, 100, 50, 10);
+ ctx.stroke();
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: If x1,y1 and x2,y2 are the same point, then arcTo must add x1,y1 to the subpath, and connect that point to x0,y0 with a straight line.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001-ref.htm
new file mode 100644
index 0000000000..6be08c0b3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001-ref.htm
@@ -0,0 +1,32 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: bezierCurveTo() must ensure subpaths</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ ctx.moveTo(65,25)
+ ctx.bezierCurveTo(65, 25, 65, 25, 65, 65);
+ ctx.stroke();
+ ctx.beginPath();
+
+ ctx.moveTo(35,25)
+ ctx.bezierCurveTo(35, 25, 35, 25, 35, 65);
+ ctx.stroke();
+ ctx.beginPath();
+
+ ctx.moveTo(0,75)
+ ctx.bezierCurveTo(0, 75, 50, 150, 100, 75);
+ ctx.stroke();
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) must ensure there is a subpath for the point (cp1x,cp1y) if the context has no subpaths, then it must connect the last point in the subpath to the point (x,y).</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas (ref test).</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001.htm b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001.htm
new file mode 100644
index 0000000000..d04926ebac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/building-paths/canvas_complexshapes_beziercurveto_001.htm
@@ -0,0 +1,35 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: bezierCurveTo() must ensure subpaths</title>
+ <link rel="match" href="canvas_complexshapes_beziercurveto_001-ref.htm">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto" />
+ <meta name="assert" content="bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) must ensure there is a subpath for the point (cp1x,cp1y) if the context has no subpaths, then it must connect the last point in the subpath to the point (x,y)." />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Since the canvas has no subpaths, a virtual moveTo must be performed to (65,25) before creating the bezier.
+ ctx.bezierCurveTo(65, 25, 65, 25, 65, 65);
+ ctx.stroke();
+ ctx.beginPath();
+
+ // Since the canvas has no subpaths, a virtual moveTo must be performed to (35,25) before creating the bezier.
+ ctx.bezierCurveTo(35, 25, 35, 25, 35, 65);
+ ctx.stroke();
+ ctx.beginPath();
+
+ // Since the canvas has no subpaths, a virtual moveTo must be performed to (0,75) before creating the bezier.
+ ctx.bezierCurveTo(0, 75, 50, 150, 100, 75);
+ ctx.stroke();
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) must ensure there is a subpath for the point (cp1x,cp1y) if the context has no subpaths, then it must connect the last point in the subpath to the point (x,y).</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow-ref.html b/testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow-ref.html
new file mode 100644
index 0000000000..3ff0ed291d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow-ref.html
@@ -0,0 +1,15 @@
+<body>
+<script>
+var canvas, ctx;
+canvas = document.createElement("canvas");
+canvas.width = 100;
+canvas.height = 100;
+document.body.appendChild(canvas);
+
+ctx = canvas.getContext("2d");
+ctx.globalAlpha = 0.5;
+ctx.shadowOffsetX = -canvas.width;
+ctx.shadowColor = 'red';
+ctx.fillRect(canvas.width,0,canvas.width,canvas.height);
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow.html b/testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow.html
new file mode 100644
index 0000000000..1df227ce0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/compositing/alpha_filter_shadow.html
@@ -0,0 +1,16 @@
+<body>
+<script>
+var canvas, ctx;
+canvas = document.createElement("canvas");
+canvas.width = 100;
+canvas.height = 100;
+document.body.appendChild(canvas);
+
+ctx = canvas.getContext("2d");
+ctx.globalAlpha = 0.5;
+ctx.shadowOffsetX = -canvas.width;
+ctx.shadowColor = 'red';
+ctx.filter = 'sepia(0)';
+ctx.fillRect(canvas.width,0,canvas.width,canvas.height);
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001-ref.htm
new file mode 100644
index 0000000000..70196fb36a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001-ref.htm
@@ -0,0 +1,11 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: globalCompositeOperation "destination-over"</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ </head>
+ <body>
+ <p>Description: If the globalCompositeOperation is set to "destination-over", display the destination image wherever the destination image is opaque.</p>
+ <div><img alt='black rectangle' src="/images/black-rectangle.png"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001.htm b/testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001.htm
new file mode 100644
index 0000000000..8d6208eb32
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/compositing/canvas_compositing_globalcompositeoperation_001.htm
@@ -0,0 +1,32 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: globalCompositeOperation "destination-over"</title>
+ <link rel="match" href="canvas_compositing_globalcompositeoperation_001-ref.htm">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-globalcompositeoperation" />
+ <meta name="assert" content="If the globalCompositeOperation is set to 'destination-over', display the destination image wherever the destination image is opaque." />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Source image.
+ ctx.fillStyle = "rgba(0, 0, 0, 1.0)";
+ ctx.fillRect(0, 0, 100, 50);
+
+ // Assign the globalCompositeOperation.
+ ctx.globalCompositeOperation = "destination-over";
+
+ // Destination image.
+ ctx.fillStyle = "rgba(255, 0, 0, 1.0)";
+ ctx.fillRect(0, 0, 100, 50);
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: If the globalCompositeOperation is set to "destination-over", display the destination image wherever the destination image is opaque.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/canvas-with-padding.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/canvas-with-padding.html
new file mode 100644
index 0000000000..5a93ef680a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/canvas-with-padding.html
@@ -0,0 +1,10 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<canvas id='c' style="padding-right: 4294967292; border-right: 124px solid black;"></canvas>
+<script>
+ test(function(t) {
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+ ctx.getImageData(0, 0, 1, 1);
+ }, '// The test case passes by not crashing.')
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false-ref.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false-ref.html
new file mode 100644
index 0000000000..eccfc4e2cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, fillRect with semi-transparent color.</title>
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d");
+ctx.fillStyle = 'black';
+ctx.fillRect(-1, -1, 102, 102);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false.html
new file mode 100644
index 0000000000..a328fbf97a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/clearRect_alpha_false.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, clearRect</title>
+<link rel="author" title="Justin Novosad" href="mailto:junov@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/#concept-canvas-alpha">
+<link rel="match" href="clearRect_alpha_false-ref.html">
+<meta name="assert" content="Canvas pixels remain opaque black when drawing semi-transparent rectangle.">
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d", {alpha: false});
+ctx.fillColor = 'red';
+ctx.fillRect(25, 25, 50, 25);
+ctx.clearRect(24, 24, 52, 52);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false-ref.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false-ref.html
new file mode 100644
index 0000000000..2c9e5620b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, drawing a transparent image.</title>
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d");
+ctx.fillStyle = 'black';
+ctx.fillRect(-1, -1, 102, 102);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false.html
new file mode 100644
index 0000000000..64f38bceb1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/drawImage_alpha_false.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, drawing a transparent image</title>
+<link rel="author" title="Justin Novosad" href="mailto:junov@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/#concept-canvas-alpha">
+<link rel="match" href="drawImage_alpha_false-ref.html">
+<meta name="assert" content="Canvas pixels remain opaque black when drawing a transparent image.">
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const source = document.createElement('canvas');
+source.width = source.height = 20;
+const source_ctx = source.getContext("2d"); // leave default transparent content
+
+const ctx = document.getElementById("c").getContext("2d", {alpha: false});
+ctx.globalCompositOperation = 'copy';
+ctx.drawImage(source, 0, 0);
+ctx.globalCompositOperation = 'source-over';
+ctx.drawImage(source, 20, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false-ref.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false-ref.html
new file mode 100644
index 0000000000..eccfc4e2cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, fillRect with semi-transparent color.</title>
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d");
+ctx.fillStyle = 'black';
+ctx.fillRect(-1, -1, 102, 102);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false.html
new file mode 100644
index 0000000000..143756eb0c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fillRect_alpha_false.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, fillRect with semi-transparent color.</title>
+<link rel="author" title="Justin Novosad" href="mailto:junov@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/#concept-canvas-alpha">
+<link rel="match" href="fillRect_alpha_false-ref.html">
+<meta name="assert" content="Canvas pixels remain opaque black when drawing semi-transparent rectangle.">
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d", {alpha: false});
+ctx.fillColor = "rgba(0, 0, 0, 0.5)";
+ctx.fillRect(25, 25, 50, 50);
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false-ref.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false-ref.html
new file mode 100644
index 0000000000..03265a656e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, path fill with transparent color and 'copy' composite operation.</title>
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d");
+ctx.fillStyle = 'black';
+ctx.fillRect(-1, -1, 102, 102);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false.html
new file mode 100644
index 0000000000..7872a79380
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/fill_alpha_false.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase, path fill with transparent color and 'copy' composite operation.</title>
+<link rel="author" title="Justin Novosad" href="mailto:junov@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/#concept-canvas-alpha">
+<link rel="match" href="fill_alpha_false-ref.html">
+<meta name="assert" content="Canvas pixels remain opaque black when filling path with tranparent pixels and 'copy' compisite op.">
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d", {alpha: false});
+ctx.fillColor = 'red';
+ctx.fillRect(25, 25, 50, 25); // will be overwritten.
+ctx.fillColor = "rgba(0, 0, 0, 0.0)";
+ctx.globalCompositeOperation = 'copy';
+ctx.rect(25, 25, 50, 50);
+ctx.fill();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/getContextAttributes.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/getContextAttributes.html
new file mode 100644
index 0000000000..47b3d96233
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/getContextAttributes.html
@@ -0,0 +1,46 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+
+var testScenarios = [
+ {testDescription: "Test default context creation attributes",
+ canvasContextAttributes: {},
+ expectedContextAttributes: {alpha: true, desynchronized: false, willReadFrequently: false}},
+ {testDescription: "Test context creation attributes alpha: true",
+ canvasContextAttributes: {alpha: true},
+ expectedContextAttributes: {alpha: true}},
+ {testDescription: "Test context creation attributes alpha: false",
+ canvasContextAttributes: {alpha: false},
+ expectedContextAttributes: {alpha: false}},
+ {testDescription: "Test context creation attributes desynchronized: false",
+ canvasContextAttributes: {desynchronized: false},
+ expectedContextAttributes: {desynchronized: false}},
+ {testDescription: "Test context creation attributes willReadFrequently: true",
+ canvasContextAttributes: {willReadFrequently: true},
+ expectedContextAttributes: {willReadFrequently: true}},
+];
+
+function runTestScenario(testScenario) {
+ var t = test(function() {
+ var canvas = document. createElement('canvas');
+ var ctx = canvas.getContext('2d', testScenario.canvasContextAttributes);
+ var contextAttributes = ctx.getContextAttributes();
+ if (testScenario.expectedContextAttributes.alpha !== undefined) {
+ assert_equals(contextAttributes.alpha,
+ testScenario.expectedContextAttributes.alpha);
+ }
+ if (testScenario.expectedContextAttributes.desynchronized !== undefined) {
+ assert_equals(contextAttributes.desynchronized,
+ testScenario.expectedContextAttributes.desynchronized);
+ }
+ }, testScenario.testDescription);
+}
+
+function runAllTests() {
+ for (var i = 0; i < testScenarios.length; i++)
+ runTestScenario(testScenarios[i]);
+}
+
+runAllTests();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false-ref.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false-ref.html
new file mode 100644
index 0000000000..b67513c464
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase context creation parameter is initialized with solid black.</title>
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d");
+ctx.fillStyle = 'black';
+ctx.fillRect(-1, -1, 102, 102);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false.html
new file mode 100644
index 0000000000..9e86e5ce2c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/initial_color_alpha_false.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase context creation parameter is initialized with solid black.</title>
+<link rel="author" title="Justin Novosad" href="mailto:junov@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/#concept-canvas-alpha">
+<link rel="match" href="initial_color_alpha_false-ref.html">
+<meta name="assert" content="Canvas pixels are initialized to opaque black when alpha attribute is false.">
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+document.getElementById("c").getContext("2d", {alpha: false});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false-ref.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false-ref.html
new file mode 100644
index 0000000000..d663131148
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase context creation parameter is re-initialized with solid black.</title>
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const ctx = document.getElementById("c").getContext("2d");
+ctx.fillStyle = 'black';
+ctx.fillRect(-1, -1, 102, 102);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false.html b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false.html
new file mode 100644
index 0000000000..191975e0f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/context-attributes/reset_color_alpha_false.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext 2D with alpha=flase context creation parameter is re-initialized with solid black.</title>
+<link rel="author" title="Justin Novosad" href="mailto:junov@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/#concept-canvas-alpha">
+<link rel="match" href="reset_color_alpha_false-ref.html">
+<meta name="assert" content="Canvas pixels are re-initialized to opaque black upon context reset.">
+<p>Test passes if a 100x100 black square is displayed below.</p>
+<canvas id="c" width=100 height=100></canvas>
+<script>
+const canvas = document.getElementById("c");
+const ctx = canvas.getContext("2d", {alpha: false});
+ctx.fillColor = 'red';
+ctx.fillRect(25, 25, 50, 50);
+canvas.width = canvas.width;
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html
new file mode 100644
index 0000000000..36bd085136
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html
@@ -0,0 +1,203 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<canvas id="dest" height="100" width="100"></canvas>
+
+<script>
+var sourceCanvasWidth = sourceCanvasHeight = 50;
+var destCanvasWidth = destCanvasHeight = 100;
+var blueRect = {x: 0, y: 0, w: 50, h: 50};
+var blackRect = {x: 5, y: 5, w: 40, h: 40};
+var redPixel = [255, 0, 0, 255];
+var bluePixel = [0, 0, 255, 255];
+var blackPixel = [0, 0, 0, 255];
+var transparentBlackPixel = [0, 0, 0, 0];
+
+var destCanvas = document.getElementById('dest');
+var destCtx = destCanvas.getContext('2d');
+destCtx.imageSmoothingEnabled = false;
+
+function checkPixel(location, expected) {
+ var actual = destCtx.getImageData(location[0], location[1], 1, 1).data;
+ assert_array_equals(actual, expected);
+}
+
+function PreparePixelTests(blueCheck, blackCheck, redCheck, testDescription) {
+ var pixelTests = [];
+ for (var i = 0; i < blueCheck.length; i++) {
+ var message = testDescription + 'Pixel ' + blueCheck[i][0] + ',' + blueCheck[i][1] + ' should be blue.';
+ pixelTests.push([message, blueCheck[i], bluePixel]);
+ }
+ for (var i = 0; i < blackCheck.length; i++) {
+ var message = testDescription + 'Pixel ' + blackCheck[i][0] + ',' + blackCheck[i][1] + ' should be black.';
+ pixelTests.push([message, blackCheck[i], blackPixel]);
+ }
+ for (var i = 0; i < redCheck.length; i++) {
+ var message = testDescription + 'Pixel ' + redCheck[i][0] + ',' + redCheck[i][1] + ' should be red.';
+ pixelTests.push([message, redCheck[i], redPixel]);
+ }
+ pixelTests.push([testDescription + 'Pixel outside canvas should be transparent black.\n', [100, 100], transparentBlackPixel]);
+ return pixelTests;
+}
+
+function drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription) {
+ destCtx.fillStyle = 'red';
+ destCtx.fillRect(0, 0, destCanvasWidth, destCanvasHeight);
+
+ var sourceCanvas = document.createElement('canvas');
+ sourceCanvas.width = sourceCanvasWidth;
+ sourceCanvas.height = sourceCanvasHeight;
+ var sourceCtx = sourceCanvas.getContext('2d');
+ sourceCtx.fillStyle = 'blue';
+ sourceCtx.fillRect(blueRect.x, blueRect.y, blueRect.w, blueRect.h);
+ sourceCtx.fillStyle = 'black';
+ sourceCtx.fillRect(blackRect.x, blackRect.y, blackRect.w, blackRect.h);
+ if (typeof sourceRect.x !== 'undefined')
+ destCtx.drawImage(sourceCanvas, sourceRect.x, sourceRect.y, sourceRect.w, sourceRect.h,
+ destRect.x, destRect.y, destRect.w, destRect.h);
+ else if (typeof destRect.w !== 'undefined')
+ destCtx.drawImage(sourceCanvas, destRect.x, destRect.y, destRect.w, destRect.h);
+ else
+ destCtx.drawImage(sourceCanvas, destRect.x, destRect.y);
+ var pixelTests = PreparePixelTests(blueCheck, blackCheck, redCheck, testDescription);
+ generate_tests(checkPixel, pixelTests);
+}
+
+var testDescription;
+var sourceRect = {}, destRect = {};
+var blueCheck, blackCheck, redCheck;
+
+// 2 arguments, the dest origin is 0,0
+// The source canvas will be copied to the 0,0 position of the destination canvas
+testDescription = 'Test scenario 1: dx = 0, dy = 0 --- ';
+destRect = {x: 0, y: 0};
+blueCheck = [[0,0], [0,49], [49,0], [49,49]];
+blackCheck = [[5,5], [5,44], [44,5], [44,44]];
+redCheck = [[50,0], [0,50], [50,50], [99,99]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// 2 arguments, the dest origin is not 0,0
+// The source canvas will copied to the 25, 25 position of the destination canvas
+testDescription = 'Test scenario 2: dx = 25, dy = 25 --- ';
+destRect = {x: 25, y: 25};
+blueCheck = [[25,25], [25,74], [74,25], [74,74]];
+blackCheck = [[30,30], [30,69], [69,30], [69,69]];
+redCheck = [[24,24], [24,75], [75,24], [75,75]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// 4 arguments, the source origin is not 0,0, the dest size is provided
+// The source canvas will copied to the 50, 50 position of the destination canvas and
+// on an area of 50x50 pixels
+testDescription = 'Test scenario 3: dx = 50, dy = 50, dw = 50, dh = 50 --- ';
+destRect = {x: 50, y: 50, w: 50, h: 50};
+blueCheck = [[50,50], [50,99], [99,50], [99,99]];
+blackCheck = [[55,55], [55,94], [94,55], [94,94]];
+redCheck = [[0,0], [49,49], [49,99], [99,49]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// 4 arguments, the dest origin is not 0,0 and the dest size is provided but
+// does not match the size of the source. The image will be distorted
+// The source canvas will copied to the 50,50 position of the destination canvas
+// and it will be shrunk to a and area of 20x20
+testDescription = 'Test scenario 4: dx = 50, dy = 50, dw = 20, dh = 20 --- ';
+destRect = {x: 50, y: 50, w: 20, h: 20};
+blueCheck = [[50,50], [50,69], [69,50], [69,69]];
+blackCheck = [[52,52], [52,67], [67,52], [67,67]];
+redCheck = [[49,49], [49,70], [70,49], [70,70]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// The source canvas will copied to the 50,50 position of the destination canvas
+// over an area of 50x25 pixels
+// The copied image will be distorted along the x axis
+testDescription = 'Test scenario 5: dx = 50, dy = 50, dw = 50, dh = 20 --- ';
+destRect = {x: 50, y: 50, w: 50, h: 20};
+blueCheck = [[50,50], [50,69], [99,50], [99,69]];
+blackCheck = [[55,52], [55,67], [94,52], [94,67]];
+redCheck = [[49,49], [49, 69], [99,49], [99,70]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// 8 arguments, both destination and source origins are 0, 0
+// An area of 25x25 pixels of the source image will be copied to
+// an area of 25x25 pixels of the destination canvas
+// destCtx.drawImage(sourceCanvas, 0, 0, 25, 25, 0, 0, 25, 25);
+testDescription = 'Test scenario 6: sx = 0, sy = 0, sw = 25, sh = 25, dx = 0, dy = 0, dw = 25, dh = 25 --- ';
+sourceRect = {x: 0, y: 0, w: 25, h: 25};
+destRect = {x: 0, y: 0, w: 25, h: 25};
+blueCheck = [[0,0], [4,4], [0,24], [24,0]];
+blackCheck = [[5,5], [5,24], [24,5], [24,24]];
+redCheck = [[25,25], [25, 99], [99,25], [99,99]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// 8 arguments the destination origin is not 0,0
+// An area of 25x25 pixels of the source image will be copied to
+// an area of 25x25 pixels of the destination canvas in the position 25,25
+testDescription = 'Test scenario 7: sx = 0, sy = 0, sw = 25, sh = 25, dx = 25, dy = 25, dw = 25, dh = 25 --- ';
+sourceRect = {x: 0, y: 0, w: 25, h: 25};
+destRect = {x: 25, y: 25, w: 25, h: 25};
+blueCheck = [[25,25], [25,49], [49,25], [29,29]];
+blackCheck = [[30,30], [30,49], [49,30], [49,49]];
+redCheck = [[24,24], [24, 50], [50,24], [50,50]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// The source rectangle overflows the source image
+// The source area is clipped to fit the source image
+// and the destination are is clipped in the same proportion
+testDescription = 'Test scenario 8: sx = 25, sy = 25, sw = 50, sh = 50, dx = 0, dy = 0, dw = 50, dh = 50 --- ';
+sourceRect = {x: 25, y: 25, w: 50, h: 50};
+destRect = {x: 0, y: 0, w: 50, h: 50};
+blueCheck = [[0,20], [20,0], [20,20], [24,24]];
+blackCheck = [[0,0], [0,19], [19,0], [19,19]];
+redCheck = [[0,25], [25, 0], [25,25], [99,99]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// The destination rectangle has negative width and height. When the source
+// rectangle is outside the source image, the source rectangle must be clipped
+// to the source image and the destination rectangle must be clipped in the same
+// proportion.
+testDescription = 'Test scenario 9: sx = 0, sy = 0, sw = 50, sh = 50, dx = 100, dy = 100, dw = -50, dh = -50 --- ';
+sourceRect = {x: 0, y: 0, w: 50, h: 50};
+destRect = {x: 100, y: 100, w: -50, h: -50};
+blueCheck = [[50,50], [50,99], [99,50], [99,99]];
+blackCheck = [[55,55], [55,94], [94,55], [94,94]];
+redCheck = [[0,0], [49,49], [0,99], [99,0]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// The destination rectangle is larger than the destination canvas
+// When the destination rectangle is outside the destination image (the scratch bitmap),
+// the pixels that land outside the scratch bitmap are discarded,
+// as if the destination was an infinite canvas whose rendering was
+// clipped to the dimensions of the scratch bitmap.
+testDescription = 'Test scenario 10: sx = 0, sy = 0, sw = 50, sh = 50, dx = 0, dy = 0, dw = 200, dh = 200 --- ';
+sourceRect = {x: 0, y: 0, w: 50, h: 50};
+destRect = {x: 0, y: 0, w: 200, h: 200};
+blueCheck = [[0,0], [0,99], [99,0], [19,19]];
+blackCheck = [[20,20], [20,99], [99,20], [99,99]];
+redCheck = [];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// The source rectangle is larger than the source canvas
+// The source area is clipped to fit the source image
+// and the destination are is clipped in the same proportion
+testDescription = 'Test scenario 11: sx = 0, sy = 0, sw = 100, sh = 100, dx = 0, dy = 0, dw = 50, dh = 50 --- ';
+sourceRect = {x: 0, y: 0, w: 100, h: 100};
+destRect = {x: 0, y: 0, w: 50, h: 50};
+blueCheck = [[0,0], [1,1], [23,23], [24,24]];
+blackCheck = [[3,3], [3,21], [21,3], [21,21]];
+redCheck = [[0,25], [25, 0], [25,25], [99,99]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+// Negative coordinates of the source rectangle.
+// The source area is clipped to fit the source image and the destination area
+// is clipped in the same proportion. In this specific test:
+// - source is clipped by 20 from top and left.
+// - destination will get proportionally clipped by 50 from top and left as we
+// are scaling the source image 2.5 times.
+// - the rect will be drawn from 70,70 to 100,100.
+testDescription = 'Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- ';
+sourceRect = {x: -20, y: -20, w: 50, h: 50};
+destRect = {x: 20, y: 20, w: 125, h: 125};
+blueCheck = [[70,70], [70,99], [99,70], [82,82]];
+blackCheck = [[84,84], [84,99], [99,84], [99,99]];
+redCheck = [[0,69], [69, 0], [69,69]];
+drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self.html
new file mode 100644
index 0000000000..83cf53583c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self.html
@@ -0,0 +1,17 @@
+<link rel="match" href="drawimage_canvas_self_ref.html">
+<canvas id="dest" height="100" width="100"></canvas>
+<script>
+var canvasWidth = canvasHeight = 100;
+var destWidth = canvasWidth / 4;
+var destHeight = canvasHeight / 4;
+var destCanvas = document.getElementById('dest');
+var destCtx = destCanvas.getContext('2d');
+
+destCtx.fillStyle = 'red';
+destCtx.fillRect(0, 0, canvasWidth, canvasHeight);
+destCtx.fillStyle = 'green';
+destCtx.fillRect(0, 0, canvasWidth / 2, canvasHeight / 2);
+destCtx.drawImage(destCanvas,
+ 0, 0, destWidth, destHeight,
+ canvasWidth / 2, canvasHeight / 2, destWidth, destHeight);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html
new file mode 100644
index 0000000000..9f297cacdc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas_self_ref.html
@@ -0,0 +1,11 @@
+<canvas id="dest" height="100" width="100"></canvas>
+<script>
+var canvasWidth = canvasHeight = 100;
+var destCanvas = document.getElementById('dest');
+var destCtx = destCanvas.getContext('2d');
+destCtx.fillStyle = 'red';
+destCtx.fillRect(0, 0, canvasWidth, canvasHeight);
+destCtx.fillStyle = 'green';
+destCtx.fillRect(0, 0, canvasWidth / 2, canvasHeight / 2);
+destCtx.fillRect(canvasWidth / 2, canvasHeight / 2, canvasWidth / 4, canvasHeight / 4);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_crossorigin.sub.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_crossorigin.sub.html
new file mode 100644
index 0000000000..3d57d9f064
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_crossorigin.sub.html
@@ -0,0 +1,61 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ function draw_and_read_image(img, should_throw) {
+ let c = document.createElement('canvas');
+ document.body.appendChild(c);
+ let ctx = c.getContext('2d');
+ ctx.drawImage(img, 0, 0);
+
+ function get_image_data() {
+ ctx.getImageData(0, 0, 4, 4);
+ }
+
+ if (should_throw) {
+ assert_throws_dom('SecurityError', get_image_data);
+ } else {
+ get_image_data();
+ }
+
+ document.body.removeChild(c);
+ }
+
+ async_test(t => {
+ let img = new Image();
+ img.src = "/images/green.png";
+ img.crossOrigin = "anonymous";
+ img.onload = t.step_func_done(() => {
+ draw_and_read_image(img, false);
+ });
+ img.onerror = t.unreached_func();
+ }, "Can get pixels of canvas with same origin image drawn");
+
+ async_test(t => {
+ let img = new Image();
+ img.src = "http://{{hosts[][www]}}:{{ports[http][0]}}/images/green.png?pipe=header(Access-Control-Allow-Origin,*)";
+ img.crossOrigin = "anonymous";
+ img.onload = t.step_func_done(() => {
+ draw_and_read_image(img, false);
+ });
+ img.onerror = t.unreached_func();
+ }, "Can get pixels of canvas with CORS enabled cross origin image drawn");
+
+ async_test(t => {
+ let img = new Image();
+ img.src = "http://{{hosts[][www]}}:{{ports[http][0]}}/images/green.png?pipe=header(Access-Control-Allow-Origin,*)";
+ img.onload = t.step_func_done(() => {
+ draw_and_read_image(img, true);
+ });
+ img.onerror = t.unreached_func();
+ }, "Can't get pixels of canvas with CORS enabled cross origin image drawn from non-CORS element");
+
+ async_test(t => {
+ let img = new Image();
+ img.src = "http://{{hosts[][www]}}:{{ports[http][0]}}/images/green.png";
+
+ img.onload = t.step_func_done(() => {
+ draw_and_read_image(img, true);
+ });
+ img.onerror = t.unreached_func();
+ }, "Can't get pixels of canvas with non-CORS enabled cross origin image drawn");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_html_image.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_html_image.html
new file mode 100644
index 0000000000..59a7d64465
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_html_image.html
@@ -0,0 +1,268 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<canvas id="dest" height="100" width="100"></canvas>
+
+<script>
+var sourceWidth = sourceHeight = 100;
+var destCanvasWidth = destCanvasHeight = 100;
+var redPixel = [255, 0, 0, 255];
+var lightPixel = [253, 140, 245, 255];
+var grayPixel = [41, 122, 115, 255];
+var transparentBlackPixel = [0, 0, 0, 0];
+
+var destCanvas = document.getElementById('dest');
+var sourceImg = document.createElement('img');
+sourceImg.src = '/html/canvas/resources/2x2.png';
+sourceImg.width = sourceWidth;
+sourceImg.height = sourceHeight;
+var destCtx = destCanvas.getContext('2d');
+destCtx.imageSmoothingEnabled = false;
+
+function checkPixel(location, expected) {
+ var actual = destCtx.getImageData(location[0], location[1], 1, 1).data;
+ assert_array_equals(actual, expected);
+}
+
+function PreparePixelTests(lightPixelCheck, grayPixelCheck, redCheck, testDescription) {
+ var pixelTests = [];
+ for (var i = 0; i < lightPixelCheck.length; i++) {
+ var message = testDescription + 'Pixel ' + lightPixelCheck[i][0] + ',' + lightPixelCheck[i][1] + ' should be light purple.';
+ pixelTests.push([message, lightPixelCheck[i], lightPixel]);
+ }
+ for (var i = 0; i < grayPixelCheck.length; i++) {
+ var message = testDescription + 'Pixel ' + grayPixelCheck[i][0] + ',' + grayPixelCheck[i][1] + ' should be gray.';
+ pixelTests.push([message, grayPixelCheck[i], grayPixel]);
+ }
+ for (var i = 0; i < redCheck.length; i++) {
+ var message = testDescription + 'Pixel ' + redCheck[i][0] + ',' + redCheck[i][1] + ' should be red.';
+ pixelTests.push([message, redCheck[i], redPixel]);
+ }
+ pixelTests.push([testDescription + 'Pixel outside canvas should be transparent black.\n', [100, 100], transparentBlackPixel]);
+ return pixelTests;
+}
+
+function drawCustomImageOnCanvas(sourceImage, sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription) {
+ destCtx.fillStyle = 'red';
+ destCtx.fillRect(0, 0, destCanvasWidth, destCanvasHeight);
+ if (typeof sourceRect.x !== 'undefined')
+ destCtx.drawImage(sourceImage, sourceRect.x, sourceRect.y, sourceRect.w, sourceRect.h,
+ destRect.x, destRect.y, destRect.w, destRect.h);
+ else if (typeof destRect.w !== 'undefined')
+ destCtx.drawImage(sourceImage, destRect.x, destRect.y, destRect.w, destRect.h);
+ else
+ destCtx.drawImage(sourceImage, destRect.x, destRect.y);
+ var pixelTests = PreparePixelTests(lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+ generate_tests(checkPixel, pixelTests);
+}
+
+function drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription) {
+ drawCustomImageOnCanvas(sourceImg, sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+var testDescription;
+var sourceRect = {}, destRect = {};
+var lightPixelCheck, grayPixelCheck, redCheck;
+
+// 2 arguments, the dest origin is 0,0
+// The source image will copied to the 0,0 position of the destination canvas
+function runDrawImageTest_dX0_dY0() {
+ testDescription = 'Test scenario 1: dx = 0, dy = 0 --- ';
+ destRect = {x: 0, y: 0};
+ lightPixelCheck = [[0,0], [0,99], [99,0], [99,99]];
+ grayPixelCheck = [];
+ redCheck = [];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// 2 arguments, the dest origin is not 0,0
+// The source canvas will copied to the 25,25 position of the destination canvas
+function runDrawImageTest_dX25_dY25() {
+ testDescription = 'Test scenario 2: dx = 25, dy = 25 --- ';
+ destRect = {x: 25, y: 25};
+ lightPixelCheck = [[25,25], [25,99], [99,25], [99,99]];
+ grayPixelCheck = [];
+ redCheck = [[0,0], [24,24], [0,25], [25,0], [0,99], [99,0]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// 4 arguments, the source origin is not 0,0, the dest size is provided
+// The source canvas will copied to the 50, 50 position of the destination canvas and
+// on an area of 50x50 pixels
+function runDrawImageTest_dX50_dY50_dW50_dH50() {
+ testDescription = 'Test scenario 3: dx = 50, dy = 50, dw = 50, dh = 50 --- ';
+ destRect = {x: 50, y: 50, w: 50, h: 50};
+ lightPixelCheck = [[50,50], [99,99]];
+ grayPixelCheck = [[50,99], [99,50]];
+ redCheck = [[0,0], [49,49], [0,50], [50,0], [0,99], [99,0]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// 4 arguments, the dest origin is not 0,0 and the dest size is provided but
+// does not match the size of the source. The image will be distorted
+// The source canvas will copied to the 50,50 position of the destination canvas
+// and it will be shrunk to a and area of 16x16
+function runDrawImageTest_dX50_dY50_dW16_dH16() {
+ testDescription = 'Test scenario 4: dx = 50, dy = 50, dw = 16, dh = 16 --- ';
+ destRect = {x: 50, y: 50, w: 16, h: 16};
+ lightPixelCheck = [[50,50], [65,65]];
+ grayPixelCheck = [[50,65], [65,50]];
+ redCheck = [[0,0], [49,49], [49,66], [66,49], [66,66], [99,99]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// The source canvas will copied to the 50,50 position of the destination canvas
+// over an area of 64x32 pixels
+// The copied image will be distorted along the x axis
+function runDrawImageTest_dX50_dY50_dW64_dH32() {
+ testDescription = 'Test scenario 5: dx = 50, dy = 50, dw = 64, dh = 32 --- ';
+ destRect = {x: 50, y: 50, w: 64, h: 32};
+ lightPixelCheck = [[50,50], [99,81]];
+ grayPixelCheck = [[50,81], [99,50]];
+ redCheck = [[0,0], [49,49], [49,82], [99,49], [99,82], [99,99]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// 8 arguments, both destination and source origins are 0, 0
+// An area of 32x32 pixels of the source image will be copied to
+// an area of 32x32 pixels of the destination canvas
+function runDrawImageTest_sX0_sY0_sW32_sH32_dX0_dY0_dW32_dH32() {
+ testDescription = 'Test scenario 6: sx = 0, sy = 0, sw = 32, sh = 32, dx = 0, dy = 0, dw = 32, dh = 32 --- ';
+ sourceRect = {x: 0, y: 0, w: 32, h: 32};
+ destRect = {x: 0, y: 0, w: 32, h: 32};
+ lightPixelCheck = [[0,0], [0,31], [31,0], [31,31]];
+ grayPixelCheck = [];
+ redCheck = [[0,32], [32,0], [32,32], [99,99]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// 8 arguments the destination origin is not 0,0
+// An area of 32x32 pixels of the source image will be copied to
+// an area of 32x32 pixels of the destination canvas in the position 32,32
+function runDrawImageTest_sX0_sY0_sW32_sH32_dX32_dY32_dW32_dH32() {
+ testDescription = 'Test scenario 7: sx = 0, sy = 0, sw = 32, sh = 32, dx = 32, dy = 32, dw = 32, dh = 32 --- ';
+ sourceRect = {x: 0, y: 0, w: 32, h: 32};
+ destRect = {x: 32, y: 32, w: 32, h: 32};
+ lightPixelCheck = [[32,32], [32,63], [63,32], [63,63]];
+ grayPixelCheck = [];
+ redCheck = [[0,0], [31,31], [31,64], [64,31], [64,64], [99,99]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// The source rectangle overflows the source image
+// The source area is clipped to fit the source image
+// and the destination are is clipped in the same proportion
+function runDrawImageTest_sX32_sY32_sW32_sH32_dX0_dY0_dW32_dH32() {
+ testDescription = 'Test scenario 8: sx = 32, sy = 32, sw = 32, sh = 32, dx = 0, dy = 0, dw = 32, dh = 32 --- ';
+ sourceRect = {x: 32, y: 32, w: 32, h: 32};
+ destRect = {x: 0, y: 0, w: 32, h: 32};
+ lightPixelCheck = [[0,0], [0,31], [31,0], [31,31]];
+ grayPixelCheck = [];
+ redCheck = [[0,32], [32,0], [32,32], [99,99]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// The destination rectangle has negative width and height. When the source
+// rectangle is outside the source image, the source rectangle must be clipped
+// to the source image and the destination rectangle must be clipped in the same
+// proportion.
+function runDrawImageTest_sX0_sY0_sW32_sH32_dX32_dY32_dWm32_dHm32() {
+ testDescription = 'Test scenario 9: sx = 32, sy = 32, sw = 32, sh = 32, dx = 32, dy = 32, dw = -32, dh = -32 --- ';
+ sourceRect = {x: 32, y: 32, w: 32, h: 32};
+ destRect = {x: 0, y: 0, w: 32, h: 32};
+ lightPixelCheck = [[0,0], [0,31], [31,0], [31,31]];
+ grayPixelCheck = [];
+ redCheck = [[0,32], [32,0], [32,32], [99,99]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// The destination rectangle is larger than the destination canvas.
+// When the destination rectangle is outside the destination image (the scratch bitmap),
+// the pixels that land outside the scratch bitmap are discarded,
+// as if the destination was an infinite canvas
+// whose rendering was clipped to the dimensions of the scratch bitmap.
+function runDrawImageTest_sX0_sY0_sW512_sH512_dX0_dY0_dW256_dH256() {
+ testDescription = 'Test scenario 10: sx = 0, sy = 0, sw = 512, sh = 512, dx = 0, dy = 0, dw = 256, dh = 256 --- ';
+ sourceRect = {x: 0, y: 0, w: 512, h: 512};
+ destRect = {x: 0, y: 0, w: 256, h: 256};
+ lightPixelCheck = [[0,0], [0,99], [99,0], [99,99]];
+ grayPixelCheck = [];
+ redCheck = [];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// The source rectangle is larger than the source canvas
+// The source area is clipped to fit the source image
+// and the destination area is clipped in the same proportion
+function runDrawImageTest_sX0_sY0_sW2048_sH2048_dX0_dY0_dW800_dH800() {
+ testDescription = 'Test scenario 11: sx = 0, sy = 0, sw = 2048, sh = 2048, dx = 0, dy = 0, dw = 800, dh = 800 --- ';
+ sourceRect = {x: 0, y: 0, w: 2048, h: 2048};
+ destRect = {x: 0, y: 0, w: 800, h: 800};
+ lightPixelCheck = [[0,0], [0,99], [99,0], [99,99]];
+ grayPixelCheck = [];
+ redCheck = [];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// Negative coordinates of the source rectangle
+// The source area is clipped to fit the source image
+// and the destination area is clipped in the same proportion
+function runDrawImageTest_sXm20_sYm20_sW50_sH50_dX20_dY20_dW125_dH125() {
+ testDescription = 'Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- ';
+ sourceRect = {x: -20, y: -20, w: 50, h: 50};
+ destRect = {x: 20, y: 20, w: 125, h: 125};
+ lightPixelCheck = [[70,70], [70,99], [99,70], [99,99]];
+ grayPixelCheck = [];
+ redCheck = [[0,0], [0,99], [99,0], [69,69], [69, 99], [99,69]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// The source Image doesn't have a src url defined.
+// No exception is thrown and nothing is drawn.
+function runDrawImageTestImageWithuotSource() {
+ testDescription = 'Test scenario 13: draw an image element that does not have a source --- ';
+ var sourceImage = document.createElement('img');
+ sourceRect = {x: 0, y: 0, w: 50, h: 50};
+ destRect = {x: 0, y: 0, w: 100, h: 100};
+ lightPixelCheck = [];
+ grayPixelCheck = [];
+ redCheck = [[0,0], [0,99], [99,0], [99,69]];
+ drawCustomImageOnCanvas(sourceImage, sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+// Clipping the source and down scaling to the destination
+function runDrawImageTest_sX64_sY64_sW384_sH384_dX0_dY0_dW32_dH64() {
+ testDescription = 'Test scenario 14: sx = 64, sy = 64, sw = 384, sh = 384, dx = 0, dy = 0, dw = 32, dh = 64 --- ';
+ sourceRect = {x: 64, y: 64, w: 384, h: 384};
+ destRect = {x: 0, y: 0, w: 32, h: 64};
+ lightPixelCheck = [[0,0], [15,31], [17,33], [31,63]];
+ grayPixelCheck = [[16,0], [31,31], [0, 33], [15,63]];
+ redCheck = [[0,64], [32,0], [32,64], [99,99]];
+ drawImageOnCanvas(sourceRect, destRect, lightPixelCheck, grayPixelCheck, redCheck, testDescription);
+}
+
+
+function runDrawImageTests() {
+ runDrawImageTest_dX0_dY0();
+ runDrawImageTest_dX25_dY25();
+ runDrawImageTest_dX50_dY50_dW50_dH50();
+ runDrawImageTest_dX50_dY50_dW16_dH16();
+ runDrawImageTest_dX50_dY50_dW64_dH32();
+ runDrawImageTest_sX0_sY0_sW32_sH32_dX0_dY0_dW32_dH32();
+ runDrawImageTest_sX0_sY0_sW32_sH32_dX32_dY32_dW32_dH32();
+ runDrawImageTest_sX32_sY32_sW32_sH32_dX0_dY0_dW32_dH32();
+ runDrawImageTest_sX0_sY0_sW32_sH32_dX32_dY32_dWm32_dHm32();
+ runDrawImageTest_sX0_sY0_sW512_sH512_dX0_dY0_dW256_dH256();
+ runDrawImageTest_sX0_sY0_sW2048_sH2048_dX0_dY0_dW800_dH800();
+ runDrawImageTest_sXm20_sYm20_sW50_sH50_dX20_dY20_dW125_dH125();
+ runDrawImageTestImageWithuotSource();
+ runDrawImageTest_sX64_sY64_sW384_sH384_dX0_dY0_dW32_dH64();
+}
+
+async_test(t => {
+ window.onload = function() {
+ t.step(runDrawImageTests);
+ t.done();
+ }
+}, 'Draw 100x100 image to 100x100 canvas at 0,0.');
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_1.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_1.html
new file mode 100644
index 0000000000..ea3300bef2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_1.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Load a 100x100 image to a SVG image and draw it to a 100x100 canvas.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<div id="log"></div>
+<canvas id="dest" height="100" width="100"></canvas>
+<script>
+async_test(t => {
+ var sourceImg = document.createElementNS('http://www.w3.org/2000/svg', 'image');
+ sourceImg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '/html/canvas/resources/2x2.png');
+ sourceImg.width = 100;
+ sourceImg.height = 100;
+
+ window.onload = t.step_func_done(() => {
+ var destCanvas = document.getElementById('dest');
+ var destCtx = destCanvas.getContext('2d');
+ destCtx.fillStyle = "#FF0000";
+ destCtx.fillRect(0, 0, destCanvas.width, destCanvas.height);
+ destCtx.imageSmoothingEnabled = false;
+ // 2 arguments, the dest origin is 0,0
+ // The source canvas will copied to the 0,0 position of the destination canvas
+ destCtx.drawImage(sourceImg, 0, 0);
+ _assertPixel(destCanvas, 0, 0, 253, 140, 245, 255);
+ _assertPixel(destCanvas, 0, 99, 253, 140, 245, 255);
+ _assertPixel(destCanvas, 99, 0, 253, 140, 245, 255);
+ _assertPixel(destCanvas, 99, 99, 253, 140, 245, 255);
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_with_foreign_object_does_not_taint.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_with_foreign_object_does_not_taint.html
new file mode 100644
index 0000000000..f29b2bf5a8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_svg_image_with_foreign_object_does_not_taint.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Draw an SVG image with a foreignObject to a canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function loadImage(url) {
+ return new Promise(resolve => {
+ const image = new window.Image();
+ image.onload = () => {
+ resolve(image);
+ };
+ image.src = url;
+ });
+}
+
+promise_test(async (t) => {
+ // Load a data URL for an SVG image with a foreign object.
+ const url = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><foreignObject></foreignObject></svg>';
+ const image = await loadImage(url);
+
+ // Draw the image to a canvas.
+ const canvas = document.createElement('canvas');
+ const context = canvas.getContext('2d');
+ canvas.width = image.width;
+ canvas.height = image.height;
+ context.drawImage(image, 0, 0);
+
+ // The canvas should not be tainted, so the following shouldn't throw.
+ assert_true(canvas.toDataURL().length > 0);
+}, 'Canvas should not be tainted after drawing SVG including <foreignObject>');
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none-ref.html
new file mode 100644
index 0000000000..320a9b8108
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference for drawImage from a createImageBitmap source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <img id="img-element" style="image-orientation: none;" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none.tentative.html
new file mode 100644
index 0000000000..39ed4a25dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-orientation-none.tentative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-bitmap-orientation-none-ref.html">
+ <script>
+ image = new Image();
+ image.src = "/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg";
+
+ let imageLoadPromise = new Promise(resolve => {
+ image.onload = resolve;
+ });
+ let contentLoadedPromise = new Promise(resolve => {
+ window.addEventListener('DOMContentLoaded', resolve);
+ });
+ Promise.all([imageLoadPromise, contentLoadedPromise]).then( function() {
+ const can = document.getElementById('bitmap-canvas');
+ can.height = 50;
+ can.width = 100;
+ can.getContext('2d').drawImage(image, 0, 0);
+ })
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <canvas id="bitmap-canvas" style="image-orientation: none;"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-ref.html
new file mode 100644
index 0000000000..261d6a0b7c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference for drawImage from a createImageBitmap source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none-ref.html
new file mode 100644
index 0000000000..3a78aad068
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference for drawImage from a createImageBitmap source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <img id="img-element" style="image-orientation: none;" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none.tentative.html
new file mode 100644
index 0000000000..3b16241c97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-orientation-none.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-bitmap-swap-width-height-orientation-none-ref.html">
+ <script>
+ image = new Image();
+ image.src = "/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg";
+
+ let imageLoadPromise = new Promise(resolve => {
+ image.onload = resolve;
+ });
+ let contentLoadedPromise = new Promise(resolve => {
+ window.addEventListener('DOMContentLoaded', resolve);
+ });
+ Promise.all([imageLoadPromise, contentLoadedPromise]).then( async function() {
+ const bitmap = await createImageBitmap(image);
+ const can = document.getElementById('bitmap-canvas');
+ can.height = 50;
+ can.width = 100;
+ can.getContext('2d').drawImage(bitmap, 0, 0);
+ })
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <canvas id="bitmap-canvas" style="image-orientation: none;"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-ref.html
new file mode 100644
index 0000000000..247d7f4049
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference for drawImage from a createImageBitmap source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height.tentative.html
new file mode 100644
index 0000000000..744ca54f47
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap-swap-width-height.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-bitmap-swap-width-height-ref.html">
+ <script>
+ image = new Image();
+ image.src = "/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg";
+
+ let imageLoadPromise = new Promise(resolve => {
+ image.onload = resolve;
+ });
+ let contentLoadedPromise = new Promise(resolve => {
+ window.addEventListener('DOMContentLoaded', resolve);
+ });
+ Promise.all([imageLoadPromise, contentLoadedPromise]).then( async function() {
+ const bitmap = await createImageBitmap(image);
+ const can = document.getElementById('bitmap-canvas');
+ can.height = 100;
+ can.width = 50;
+ can.getContext('2d').drawImage(bitmap, 0, 0);
+ })
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <canvas id="bitmap-canvas"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap.tentative.html
new file mode 100644
index 0000000000..632a170b88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-bitmap.tentative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-bitmap-ref.html">
+ <script>
+ image = new Image();
+ image.src = "/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg";
+
+ let imageLoadPromise = new Promise(resolve => {
+ image.onload = resolve;
+ });
+ let contentLoadedPromise = new Promise(resolve => {
+ window.addEventListener('DOMContentLoaded', resolve);
+ });
+ Promise.all([imageLoadPromise, contentLoadedPromise]).then( function() {
+ const can = document.getElementById('bitmap-canvas');
+ can.height = 50;
+ can.width = 100;
+ can.getContext('2d').drawImage(image, 0, 0);
+ })
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <canvas id="bitmap-canvas"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob-ref.html
new file mode 100644
index 0000000000..2bd6037835
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from a blob with image orientation: from-image, reference</title>
+</head>
+<body>
+ <img id="img-element" style="width: 150px; height: 300px;" src="/css/css-images/image-orientation/support/exif-orientation-8-llo.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob.tentative.html
new file mode 100644
index 0000000000..330b3cbfe5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-blob.tentative.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from a blob with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-blob-ref.html">
+ <script>
+ function makeBlob() {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/css/css-images/image-orientation/support/exif-orientation-8-llo.jpg');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ }
+
+ window.onload = function() {
+ var cfb = document.getElementById("canvasWithFileBitmap");
+ makeBlob().then(function(blob){createImageBitmap(blob).then(bitmap => {
+ cfb.getContext("2d").drawImage(bitmap, 0, 0, 150, 150 * bitmap.height / bitmap.width);
+ window.requestAnimationFrame(() => {
+ document.documentElement.removeAttribute("class");
+ });
+ });
+ });
+ }
+</script>
+</head>
+<body>
+ <canvas id="canvasWithFileBitmap" width="150" height="300"></canvas>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none-ref.html
new file mode 100644
index 0000000000..b847b9eb73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference for drawImage from an element source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <img id="img-element" style="image-orientation: none;" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none.tentative.html
new file mode 100644
index 0000000000..61563da738
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-orientation-none.tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-element-orientation-none-ref.html">
+ <script>
+ window.onload = () => {
+ const img = document.getElementById('img-element');
+
+ const can = document.getElementById('bitmap-canvas');
+ can.height = img.height;
+ can.width = img.width;
+ can.getContext('2d').drawImage(img, 0, 0);
+ };
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <canvas id="bitmap-canvas" style="image-orientation: none;"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-ref.html
new file mode 100644
index 0000000000..3f4d1e5ff4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference for drawImage from an element source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none-ref.html
new file mode 100644
index 0000000000..b26154b40a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference drawImage from an element source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <img id="img-element" style="image-orientation: none;" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none.tentative.html
new file mode 100644
index 0000000000..290d7acf3a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-orientation-none.tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: none</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-element-swap-width-height-orientation-none-ref.html">
+ <script>
+ window.onload = () => {
+ const img = document.getElementById('img-element');
+
+ const can = document.getElementById('bitmap-canvas');
+ can.height = 50;
+ can.width = 100;
+ can.getContext('2d').drawImage(img, 0, 0);
+ };
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <canvas id="bitmap-canvas" style="image-orientation: none;"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-ref.html
new file mode 100644
index 0000000000..21f0f88b88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference drawImage from an element source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height.tentative.html
new file mode 100644
index 0000000000..20d59358b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element-swap-width-height.tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-element-swap-width-height-ref.html">
+ <script>
+ window.onload = () => {
+ const img = document.getElementById('img-element');
+
+ const can = document.getElementById('bitmap-canvas');
+ can.height = 100;
+ can.width = 50;
+ can.getContext('2d').drawImage(img, 0, 0);
+ };
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-7-rl.jpg">
+ <canvas id="bitmap-canvas"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.tentative.html
new file mode 100644
index 0000000000..62cdf20c79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-element.tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>createImageBitmap and drawImage from an element source with image orientation: from-image</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-from-element-ref.html">
+ <script>
+ window.onload = () => {
+ const img = document.getElementById('img-element');
+
+ const can = document.getElementById('bitmap-canvas');
+ can.height = img.height;
+ can.width = img.width;
+ can.getContext('2d').drawImage(img, 0, 0);
+ };
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <canvas id="bitmap-canvas"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect-ref.html
new file mode 100644
index 0000000000..19ffcc39c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>reference for drawImage with image orientation: from-image and a sub-image source rect</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+ <script>
+ window.onload = () => {
+ const img = document.getElementById('img-element');
+
+ const can = document.getElementById('bitmap-canvas');
+ can.height = img.height;
+ can.width = img.width;
+ can.getContext('2d').drawImage(img, 40, 20, 50, 25, 0, 0, can.width, can.height);
+ };
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr-pre-rotated.jpg">
+ <canvas id="bitmap-canvas"></canvas>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect.tentative.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect.tentative.html
new file mode 100644
index 0000000000..d889e39302
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-with-src-rect.tentative.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>drawImage with image orientation: from-image and a sub-image source rect</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#propdef-image-orientation">
+<link rel="match" href="drawImage-with-src-rect-ref.html">
+<meta name=fuzzy content="0-3;0-200">
+ <script>
+ window.onload = () => {
+ const img = document.getElementById('img-element');
+
+ const can = document.getElementById('bitmap-canvas');
+ can.height = img.height;
+ can.width = img.width;
+ can.getContext('2d').drawImage(img, 40, 20, 50, 25, 0, 0, can.width, can.height);
+ };
+ </script>
+</head>
+<body>
+ <img id="img-element" src="/css/css-images/image-orientation/support/exif-orientation-3-lr.jpg">
+ <canvas id="bitmap-canvas"></canvas>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_complexshapes_ispointInpath_001.htm b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_complexshapes_ispointInpath_001.htm
new file mode 100644
index 0000000000..18c3c9afb9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_complexshapes_ispointInpath_001.htm
@@ -0,0 +1,31 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: isPointInPath() unaffected by the current transformation matrix</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath" />
+ <meta name="assert" content="isPointInPath must check the point (x, y) as coordinates unaffected by the current transformation matrix." />
+ <script type="text/javascript">
+ async_test(function(t) {
+ window.addEventListener("load", t.step_func_done(function runTest() {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Create a path that is transformed by a translation transformation matrix.
+ ctx.translate(100, 50);
+ ctx.rect(0, 0, 100, 50);
+
+ // Ensure that the coordinates passed to isPointInPath are unaffected by the current transformation matrix.
+ assert_true(ctx.isPointInPath(125, 75), "isPointInPath(125, 75)");
+ assert_false(ctx.isPointInPath(25, 25), "!isPointInPath(25, 25)");
+ }));
+ }, "isPointInPath unaffected by transformation matrix");
+ </script>
+ </head>
+ <body>
+ <p>Description: isPointInPath must check the point (x, y) as coordinates unaffected by the current transformation matrix.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_focus_drawFocusIfNeeded_AAPI_001-manual.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_focus_drawFocusIfNeeded_AAPI_001-manual.html
new file mode 100644
index 0000000000..bf38fa68b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/canvas_focus_drawFocusIfNeeded_AAPI_001-manual.html
@@ -0,0 +1,50 @@
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>drawFocusIfNeeded() - AAPI test</title>
+ <link rel="author" title="Mark Sadecki" href="mark@w3.org">
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-drawFocusIfNeeded">
+
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This manual test can be used to verify that drawFocusIfNeeded actually updates the accessible location information (i.e. UIAutomation's CurrentBoundingRectangle) in the Accessibility API. To perform this test, you will need an <a href="http://www.w3.org/WAI/PF/wiki/ARIA_Test_Plan#Test_tools">accessibility API inspector</a>. To perform this test, use the <code>tab</code> key to move from the first focusable element to through to the fourth. This test passes if the first parameter of the bounding rectangle increases by 100 when focus is moved from the gray square to the orange square.</p>
+ <p><a href="http://www.w3.org">First focusable element</a></p>
+ <canvas height=100 width=200 id=canvas>
+ <a href='http://www.w3.org' id='button1'>Second focusable element</a>
+ <a href='http://www.w3.org' id='button2'>Third focusable element</a>
+ </canvas>
+ <p><a href="http://www.w3.org">Fourth focusable element</a></p>
+
+ <script>
+ var button1 = document.getElementById('button1');
+ var button2 = document.getElementById('button2');
+ var canvas = document.getElementById('canvas');
+ var buttons = canvas.getElementsByTagName('a');
+
+ for (var i = 0; i < buttons.length; i++) {
+ buttons[i].addEventListener('focus', drawCanvas, false);
+ buttons[i].addEventListener('blur', drawCanvas, false);
+ }
+
+ function drawRect(context, color, element) {
+ context.beginPath();
+ context.rect(10, 10, 80, 80);
+ context.fillStyle = color;
+ context.fill();
+ context.drawFocusIfNeeded(element);
+ }
+
+ function drawCanvas() {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+ context.clearRect (0, 0, 200, 100);
+
+ drawRect(context, "gray", button1);
+ context.translate(100,0);
+ drawRect(context, "orange", button2);
+ }
+ drawCanvas();
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_001.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_001.html
new file mode 100644
index 0000000000..6daf32a2af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_001.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>drawFocusIfNeeded()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="W3C">
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-drawFocusIfNeeded">
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test uses drawFocusIfNeeded to draw a focus ring in the canvas, then compare the ImageData before and after the invocation of the method to check that the focus ring was actually drawn.</p>
+ <div>
+ <p>Before:</p>
+ <canvas height=100 width=100 id='original'>
+ </canvas>
+ <p>After:</p>
+ <canvas height=100 width=100 id=canvas>
+ <label><a href='http://www.w3.org' id='element'>Focus</a></label>
+ </canvas>
+ </div>
+ <script>
+ test(function() {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+ var element = document.getElementById('element');
+ element.focus();
+ context.fillStyle = 'white';
+ context.fillRect(0, 0, 100, 100);
+ context.beginPath();
+ context.strokeStyle = 'black';
+ context.rect(10, 10, 80, 80);
+ context.stroke();
+ context.save();
+ var refImage = context.getImageData(0, 0, 100, 100);
+
+ assert_equals(40000, refImage.data.length, "ImageData.data.length is 40000");
+
+ var original = document.getElementById('original');
+ var o_context = original.getContext('2d');
+ o_context.fillStyle = 'white';
+ o_context.fillRect(0, 0, 100, 100);
+ o_context.putImageData(refImage, 0, 0, 0, 0, 100, 100);
+
+ context.rect(5, 5, 90, 90);
+ context.drawFocusIfNeeded(element);
+
+ var ringImage = context.getImageData(0, 0, 100, 100);
+ assert_equals(40000, ringImage.data.length, "ImageData.data.length is 40000");
+
+ // make sure refImage and ringImage are different
+ var length = 40000;
+ var index = length;
+ var identical = true;
+ while (--index > 0) {
+ if (refImage.data[index] != ringImage.data[index]) identical = false;
+ }
+
+ assert_false(identical, "The focus ring must appear in the canvas");
+
+
+ }, 'drawFocusIfNeeded draws a focus ring.');
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_002.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_002.html
new file mode 100644
index 0000000000..ec0a4ef427
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_002.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>drawFocusIfNeeded()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="W3C">
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-drawFocusIfNeeded">
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test uses drawFocusIfNeeded does nothing if the element is not in focus but comparing ImageData from before and after.</p>
+ <div>
+ <p>Before:</p>
+ <canvas height=100 width=100 id='original'>
+ </canvas>
+ <p>After:</p>
+ <canvas height=100 width=100 id=canvas>
+ <label><a href='http://www.w3.org' id='element'>Focus</a></label>
+ </canvas>
+ </div>
+ <script>
+ test(function() {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+ var element = document.getElementById('element');
+ context.fillStyle = 'white';
+ context.fillRect(0, 0, 100, 100);
+ context.beginPath();
+ context.strokeStyle = 'black';
+ context.rect(10, 10, 80, 80);
+ context.stroke();
+ context.save();
+ var refImage = context.getImageData(0, 0, 100, 100);
+
+ assert_equals(40000, refImage.data.length, "ImageData.data.length is 40000");
+
+ var original = document.getElementById('original');
+ var o_context = original.getContext('2d');
+ o_context.fillStyle = 'white';
+ o_context.fillRect(0, 0, 100, 100);
+ o_context.putImageData(refImage, 0, 0, 0, 0, 100, 100);
+
+
+
+ context.strokeStyle = 'blue';
+ context.rect(5, 5, 90, 90);
+ context.drawFocusIfNeeded(element);
+
+ var ringImage = context.getImageData(0, 0, 100, 100);
+ assert_equals(40000, ringImage.data.length, "ImageData.data.length is 40000");
+
+ // make sure refImage and ringImage are different
+ var length = 40000;
+ var index = length;
+ var identical = true;
+ while (--index > 0) {
+ if (refImage.data[index] != ringImage.data[index]) identical = false;
+ }
+
+ assert_true(identical, "No focus ring appears in the canvas");
+
+
+ }, 'drawFocusIfNeeded does not draw a focus ring if the element is not in focus.');
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_003.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_003.html
new file mode 100644
index 0000000000..b62c0641f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_003.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>drawFocusIfNeeded()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="W3C">
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-drawFocusIfNeeded">
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test uses drawFocusIfNeeded does nothing if the element is not a descendant but comparing ImageData from before and after.</p>
+ <div>
+ <p>Before:</p>
+ <canvas height=100 width=100 id='original'>
+ <label><a href='http://www.w3.org' id='element'>Focus</a></label>
+ </canvas>
+ <p>After:</p>
+ <canvas height=100 width=100 id=canvas>
+ </canvas>
+ </div>
+ <script>
+ test(function() {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+ var element = document.getElementById('element');
+ element.focus();
+ context.fillStyle = 'white';
+ context.fillRect(0, 0, 100, 100);
+ context.beginPath();
+ context.strokeStyle = 'black';
+ context.rect(10, 10, 80, 80);
+ context.stroke();
+ context.save();
+ var refImage = context.getImageData(0, 0, 100, 100);
+
+ assert_equals(40000, refImage.data.length, "ImageData.data.length is 40000");
+
+ var original = document.getElementById('original');
+ var o_context = original.getContext('2d');
+ o_context.fillStyle = 'white';
+ o_context.fillRect(0, 0, 100, 100);
+ o_context.putImageData(refImage, 0, 0, 0, 0, 100, 100);
+
+
+
+ context.strokeStyle = 'blue';
+ context.rect(5, 5, 90, 90);
+ context.drawFocusIfNeeded(element);
+
+ var ringImage = context.getImageData(0, 0, 100, 100);
+ assert_equals(40000, ringImage.data.length, "ImageData.data.length is 40000");
+
+ // make sure refImage and ringImage are different
+ var length = 40000;
+ var index = length;
+ var identical = true;
+ while (--index > 0) {
+ if (refImage.data[index] != ringImage.data[index]) identical = false;
+ }
+
+ assert_true(identical, "No focus ring appears in the canvas");
+
+
+ }, 'drawFocusIfNeeded does not draw a focus ring if the element is not a descendant of the context.');
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_004.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_004.html
new file mode 100644
index 0000000000..326db0daa8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_004.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>drawFocusIfNeeded()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="W3C">
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-drawFocusIfNeeded">
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test uses drawFocusIfNeeded to draw a complex path focus then compare ImageData from before and after.</p>
+ <div>
+ <p>Before:</p>
+ <canvas height=100 width=100 id='original'>
+ </canvas>
+ <p>After:</p>
+ <canvas height=100 width=100 id=canvas>
+ <label><a href='http://www.w3.org' id='element'>Focus</a></label>
+ </canvas>
+ </div>
+ <script>
+ test(function() {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+ var element = document.getElementById('element');
+ element.focus();
+ context.fillStyle = 'white';
+ context.fillRect(0, 0, 100, 100);
+ context.beginPath();
+ context.strokeStyle = 'black';
+
+ context.moveTo(10, 40);
+ context.lineTo(50, 10);
+ context.lineTo(90, 40);
+ context.lineTo(70, 40);
+ context.lineTo(70, 90);
+ context.lineTo(30, 90);
+ context.lineTo(30, 40);
+ context.closePath();
+
+ context.stroke();
+ context.save();
+ var refImage = context.getImageData(0, 0, 100, 100);
+
+ assert_equals(40000, refImage.data.length, "ImageData.data.length is 40000");
+
+ var original = document.getElementById('original');
+ var o_context = original.getContext('2d');
+ o_context.fillStyle = 'white';
+ o_context.fillRect(0, 0, 100, 100);
+ o_context.putImageData(refImage, 0, 0, 0, 0, 100, 100);
+
+
+
+ context.beginPath();
+ context.moveTo(5, 40);
+ context.lineTo(50, 5);
+ context.lineTo(95, 40);
+ context.lineTo(95, 45);
+ context.lineTo(75, 45);
+ context.lineTo(75, 95);
+ context.lineTo(25, 95);
+ context.lineTo(25, 45);
+ context.lineTo(5, 45);
+ context.closePath();
+
+ context.drawFocusIfNeeded(element);
+
+ var ringImage = context.getImageData(0, 0, 100, 100);
+ assert_equals(40000, ringImage.data.length, "ImageData.data.length is 40000");
+
+ // make sure refImage and ringImage are different
+ var length = 40000;
+ var index = length;
+ var identical = true;
+ while (--index > 0) {
+ if (refImage.data[index] != ringImage.data[index]) identical = false;
+ }
+
+ assert_false(identical, "A focus ring appears in the canvas");
+
+
+ }, 'drawFocusIfNeeded does draw a focus ring if the element is in focus.');
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_005.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_005.html
new file mode 100644
index 0000000000..96a4e3fd5d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-paths-to-the-canvas/drawFocusIfNeeded_005.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>drawFocusIfNeeded()</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="W3C">
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-drawFocusIfNeeded">
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>This test uses drawFocusIfNeeded to draw a complex path focus then compare ImageData from before and after.</p>
+ <div>
+ <p>Before:</p>
+ <canvas height=100 width=100 id='original'>
+ </canvas>
+ <p>After:</p>
+ <canvas height=100 width=100 id=canvas>
+ <p id='element' tabindex='1'>This is text.</p>
+ </canvas>
+ </div>
+ <script>
+ test(function() {
+ var canvas = document.getElementById('canvas');
+ var context = canvas.getContext('2d');
+ var element = document.getElementById('element');
+ element.focus();
+ context.fillStyle = 'white';
+ context.fillRect(0, 0, 100, 100);
+ context.beginPath();
+ context.strokeStyle = 'black';
+
+ context.moveTo(10, 40);
+ context.lineTo(50, 10);
+ context.lineTo(90, 40);
+ context.lineTo(70, 40);
+ context.lineTo(70, 90);
+ context.lineTo(30, 90);
+ context.lineTo(30, 40);
+ context.closePath();
+
+ context.stroke();
+ context.save();
+ var refImage = context.getImageData(0, 0, 100, 100);
+
+ assert_equals(40000, refImage.data.length, "ImageData.data.length is 40000");
+
+ var original = document.getElementById('original');
+ var o_context = original.getContext('2d');
+ o_context.fillStyle = 'white';
+ o_context.fillRect(0, 0, 100, 100);
+ o_context.putImageData(refImage, 0, 0, 0, 0, 100, 100);
+
+
+
+ context.beginPath();
+ context.moveTo(5, 40);
+ context.lineTo(50, 5);
+ context.lineTo(95, 40);
+ context.lineTo(95, 45);
+ context.lineTo(75, 45);
+ context.lineTo(75, 95);
+ context.lineTo(25, 95);
+ context.lineTo(25, 45);
+ context.lineTo(5, 45);
+ context.closePath();
+
+ context.drawFocusIfNeeded(element);
+
+ var ringImage = context.getImageData(0, 0, 100, 100);
+ assert_equals(40000, ringImage.data.length, "ImageData.data.length is 40000");
+
+ // make sure refImage and ringImage are different
+ var length = 40000;
+ var index = length;
+ var identical = true;
+ while (--index > 0) {
+ if (refImage.data[index] != ringImage.data[index]) identical = false;
+ }
+
+ assert_false(identical, "A focus ring appears in the canvas");
+
+
+ }, 'drawFocusIfNeeded does draw a focus ring if the element is in focus and the user activated a particular focus ring.');
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math-ref.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math-ref.html
new file mode 100644
index 0000000000..6c5dab9f41
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>font-size: math treated as medium in disconnected canvas (reference)</title>
+<body>
+</body>
+<script>
+var d = new Document();
+var c = d.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+var ctx = c.getContext("2d");
+ctx.font = `medium serif`;
+ctx.fillText("Hello World!", 5, c.height / 2);
+c.toBlob((blob) => {
+ var img = document.createElement("img");
+ const url = URL.createObjectURL(blob);
+ img.src = url;
+ img.style.border = "3px solid cyan";
+ document.body.appendChild(img);
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html b/testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html
new file mode 100644
index 0000000000..2cecff68f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>font-size: math treated as medium in disconnected canvas</title>
+<link rel="match" href="canvas.2d.disconnected-font-size-math-ref.html">
+<body>
+</body>
+<script>
+var d = new Document();
+var c = d.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+var ctx = c.getContext("2d");
+ctx.font = `math serif`;
+ctx.fillText("Hello World!", 5, c.height / 2);
+c.toBlob((blob) => {
+ var img = document.createElement("img");
+ const url = URL.createObjectURL(blob);
+ img.src = url;
+ img.style.border = "3px solid cyan";
+ document.body.appendChild(img);
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/2d.fillStyle.parse.current.notrendered.html b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/2d.fillStyle.parse.current.notrendered.html
new file mode 100644
index 0000000000..37701bacee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/2d.fillStyle.parse.current.notrendered.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.fillStyle.parse.current.notrendered</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.fillStyle.parse.current.basic</h1>
+<p class="desc">currentColor is computed from the canvas element</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("currentColor is computed from the canvas element even when element is not rendered");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('style', 'color: #0f0;');
+canvas.style.display = 'none';
+canvas.offsetTop;
+ctx.fillStyle = 'currentColor';
+canvas.style.display = 'inline';
+ctx.fillRect(0, 0, 100, 50);
+_assertPixel(canvas, 50,25, 0,255,0,255);
+
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/canvas_colorsandstyles_createlineargradient_001.htm b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/canvas_colorsandstyles_createlineargradient_001.htm
new file mode 100644
index 0000000000..5b77c98de7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/canvas_colorsandstyles_createlineargradient_001.htm
@@ -0,0 +1,59 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: createlinearGradient() with two points same</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-createlineargradient" />
+ <meta name="assert" content="If the two points in a linear gradient have identical x,y coordinates, the canvas must paint nothing." />
+ <script type="text/javascript">
+ async_test(function(t) {
+ window.addEventListener("load", t.step_func_done(function runTest() {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+ var width = canvas.width;
+ var height = canvas.height;
+
+ // Start by drawing a left to right, green-to-blue linear gradient.
+ var lingrad = ctx.createLinearGradient(0, 50, 100, 50);
+ lingrad.addColorStop(0, "rgba(0, 255, 0, 1.0)");
+ lingrad.addColorStop(1, "rgba(0, 0, 255, 1.0)");
+ ctx.fillStyle = lingrad;
+ ctx.fillRect(0, 0, 100, 50);
+
+ // Get the current state of the canvas
+ var initial = ctx.getImageData(0, 0, width, height);
+
+ // Nothing must be drawn if the two points in the linear gradient are the same.
+ lingrad = ctx.createLinearGradient(100, 100, 100, 100);
+ lingrad.addColorStop(0, "rgba(255, 0, 0, 1.0)");
+ lingrad.addColorStop(1, "rgba(255, 0, 0, 1.0)");
+ ctx.fillStyle = lingrad;
+ ctx.fillRect(0, 0, 300, 150);
+
+ // Check that nothing is drawn.
+ var after = ctx.getImageData(0, 0, width, height);
+
+ // Asserts
+ assert_equals(initial.width, after.width, "widths are equal");
+ assert_equals(initial.height, after.height, "heights are equal");
+ assert_array_equals(initial.data, after.data, "data are equal");
+
+ for (var i = 0; i < after.data.length; i += 4) {
+ var r = after.data[i];
+ var g = after.data[i+1];
+ var b = after.data[i+2];
+ var a = after.data[i+3];
+ assert_false(r == 0xFF && g == 0 && b == 0 && a == 0xFF, "no red");
+ }
+ }));
+ }, "linear gradient from point to self draws nothing");
+ </script>
+ </head>
+ <body>
+ <p>Description: If the two points in a linear gradient have identical x,y coordinates, the canvas must paint nothing.</p>
+ <p>Test passes if there is one left-to-right, green-to-blue linear gradient seen on the page and no red is seen on the page.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-expected.html b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-expected.html
new file mode 100644
index 0000000000..f347abc9d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title></title>
+ <style type="text/css">
+ div {
+ width: 300px;
+ height: 150px;
+ background: conic-gradient(
+ from 90deg at 100px 50px,
+ red 0.2turn,
+ orange 0.2turn 0.4turn,
+ yellow 0.4turn 0.6turn,
+ green 0.6turn 0.8turn,
+ blue 0.8turn 1.0turn
+ );
+ </style>
+</head>
+<body>
+ <div id="output"></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation-expected.html b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation-expected.html
new file mode 100644
index 0000000000..68d750f462
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title></title>
+ <style type="text/css">
+ div {
+ width: 300px;
+ height: 150px;
+ background: conic-gradient(
+ from 180deg at 100px 50px,
+ red 0.2turn,
+ orange 0.2turn 0.4turn,
+ yellow 0.4turn 0.6turn,
+ green 0.6turn 0.8turn,
+ blue 0.8turn 1.0turn
+ );
+ </style>
+</head>
+<body>
+ <div id="output"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation.html b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation.html
new file mode 100644
index 0000000000..e8b213b3d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient-rotation.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Conic gradient</title>
+ <link rel="match" href="conic-gradient-rotation-expected.html"/>
+</head>
+<body>
+ <canvas id="c"></canvas>
+ <script type="text/javascript">
+ const canvas = document.getElementById('c');
+ const ctx = canvas.getContext('2d');
+
+ const grad = ctx.createConicGradient(2.5*Math.PI, 100, 50);
+
+ grad.addColorStop(0, "red");
+ grad.addColorStop(0.2, "red");
+ grad.addColorStop(0.2, "orange");
+ grad.addColorStop(0.4, "orange");
+ grad.addColorStop(0.4, "yellow");
+ grad.addColorStop(0.6, "yellow");
+ grad.addColorStop(0.6, "green");
+ grad.addColorStop(0.8, "green");
+ grad.addColorStop(0.8, "blue");
+
+ ctx.fillStyle = grad;
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ </script>
+
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient.html b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient.html
new file mode 100644
index 0000000000..73fcf6c23e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/fill-and-stroke-styles/conic-gradient.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Conic gradient</title>
+ <link rel="match" href="conic-gradient-expected.html"/>
+</head>
+<body>
+ <canvas id="c"></canvas>
+ <script type="text/javascript">
+ const canvas = document.getElementById('c');
+ const ctx = canvas.getContext('2d');
+
+ const grad = ctx.createConicGradient(0, 100, 50);
+
+ grad.addColorStop(0, "red");
+ grad.addColorStop(0.2, "red");
+ grad.addColorStop(0.2, "orange");
+ grad.addColorStop(0.4, "orange");
+ grad.addColorStop(0.4, "yellow");
+ grad.addColorStop(0.6, "yellow");
+ grad.addColorStop(0.6, "green");
+ grad.addColorStop(0.8, "green");
+ grad.addColorStop(0.8, "blue");
+
+ ctx.fillStyle = grad;
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ </script>
+
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html
new file mode 100644
index 0000000000..b5f9d98b89
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-fillStyle-opacity.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-14000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'rgba(0, 128, 128, 0.75)';
+ ctx.fillRect(10, 10, 50, 50);
+ ctx.fillStyle = 'rgba(255, 0, 255, 0.5)';
+ ctx.fillRect(70, 10, 50, 50);
+ ctx.fillStyle = 'rgba(255, 165, 0, 0.25)';
+ ctx.fillRect(10, 70, 50, 50);
+ ctx.fillStyle = 'rgba(210, 105, 30, 0)';
+ ctx.fillRect(70, 70, 50, 50);
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.8)';
+ ctx.fillRect(10, 150, 50, 50);
+ ctx.fillStyle = 'rgba(255, 0, 0, 0.6)';
+ ctx.fillRect(20, 150, 50, 50);
+ ctx.fillStyle = 'rgba(255, 255, 0, 0.4)';
+ ctx.fillRect(30, 150, 50, 50);
+ ctx.fillStyle = 'rgba(0, 128, 0, 0.2)';
+ ctx.fillRect(40, 150, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html
new file mode 100644
index 0000000000..f87794f0b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle-expected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<body>
+ <div id="sq-1"></div>
+ <div id="sq-2"></div>
+ <div id="sq-3"></div>
+ <div id="sq-4"></div>
+</body>
+<style>
+ /*The expected behavior when setting the opacity through different methods
+ is that the opacity of the resulting drawn element is the product of the opacity
+ value set by each of the methods.*/
+ div{
+ width: 50px;
+ height: 50px;
+ position: absolute;
+ }
+ #sq-1{
+ background-color: black;
+ left: 18px;
+ top: 18px;
+ opacity: 0.125;
+ }
+ #sq-2{
+ background-color: black;
+ left: 78px;
+ top: 18px;
+ opacity: 0.03125;
+ }
+ #sq-3{
+ background-color: black;
+ left: 18px;
+ top: 78px;
+ opacity: 0.1875;
+ }
+ #sq-4{
+ background-color: black;
+ left: 78px;
+ top: 78px;
+ opacity: 0.016;
+ }
+</style>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html
new file mode 100644
index 0000000000..24c97d62ec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity-alpha-and-fillStyle.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-opacity-alpha-and-fillStyle-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-10000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior when setting the opacity through different methods
+ is that the opacity of the resulting drawn element is the product of the opacity
+ value set by each of the methods.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
+ ctx.filter = 'opacity(50%)';
+ ctx.fillRect(10, 10, 50, 50);
+
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'rgba(0,0,0,0.25)';
+ ctx.filter = 'opacity(25%)';
+ ctx.fillRect(70, 10, 50, 50);
+
+ ctx.globalAlpha = 0.75;
+ ctx.fillStyle = 'rgba(0,0,0,0.5)';
+ ctx.filter = 'opacity(50%)';
+ ctx.fillRect(10, 70, 50, 50);
+
+ ctx.globalAlpha = 0.8;
+ ctx.fillStyle = 'rgba(0,0,0,0.2)';
+ ctx.filter = 'opacity(10%)';
+ ctx.fillRect(70, 70, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html
new file mode 100644
index 0000000000..cb2fc018af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-opacity.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-14000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'opacity(75%)';
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(10, 10, 50, 50);
+ ctx.filter = 'opacity(50%)';
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(70, 10, 50, 50);
+ ctx.filter = 'opacity(25%)';
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(10, 70, 50, 50);
+ ctx.filter = 'opacity(0%)';
+ ctx.fillStyle = 'chocolate';
+ ctx.fillRect(70, 70, 50, 50);
+
+ ctx.filter = 'opacity(80%)';
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 150, 50, 50);
+ ctx.filter = 'opacity(60%)';
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 150, 50, 50);
+ ctx.filter = 'opacity(40%)';
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(30, 150, 50, 50);
+ ctx.filter = 'opacity(20%)';
+ ctx.fillStyle = 'green';
+ ctx.fillRect(40, 150, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html
new file mode 100644
index 0000000000..1f218b4bd2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur-expected.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The shadow and shadow blur effects should be the same regardless if they were
+ defined with filters or properties. The blur parameter is set as double when
+ using the shadowBlur property since its uses havlf of the value set as the
+ standard deviation for the gaussian blur (https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-shadowblur-dev)
+ while the filter parameter is used directly as the standard deviation
+ (https://drafts.fxtf.org/filter-effects/#funcdef-filter-drop-shadow). The
+ fuzziness is defined with a maxDifference of 13 as to be the 5% of 256, since
+ the CSS spec defines the expected behavior in relation to an ideal Gaussian blur
+ with a tolerance of 5%. See: https://drafts.csswg.org/css-backgrounds-3/#shadow-blur.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowBlur = 4;
+ ctx.shadowColor = 'red';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.shadowBlur = 8;
+ ctx.shadowColor = 'blue';
+ ctx.fillRect(100, 20, 50, 50);
+ ctx.shadowBlur = 20;
+ ctx.shadowColor = 'yellow';
+ ctx.fillRect(20, 100, 50, 50);
+ ctx.shadowBlur = 30;
+ ctx.shadowColor = 'cyan';
+ ctx.fillRect(100, 100, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html
new file mode 100644
index 0000000000..ab3699906d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-blur.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-shadow-and-properties-blur-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-13; totalPixels=0-25600">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The shadow and shadow blur effects should be the same regardless if they were
+ defined with filters or properties. The blur parameter is set as double when
+ using the shadowBlur property since its uses havlf of the value set as the
+ standard deviation for the gaussian blur (https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-shadowblur-dev)
+ while the filter parameter is used directly as the standard deviation
+ (https://drafts.fxtf.org/filter-effects/#funcdef-filter-drop-shadow). The
+ fuzziness is defined with a maxDifference of 13 as to be the 5% of 256, since
+ the CSS spec defines the expected behavior in relation to an ideal Gaussian blur
+ with a tolerance of 5%. See: https://drafts.csswg.org/css-backgrounds-3/#shadow-blur.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'drop-shadow(10px 10px 2px red)';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.filter = 'drop-shadow(10px 10px 4px blue)';
+ ctx.fillRect(100, 20, 50, 50);
+ ctx.filter = 'drop-shadow(10px 10px 10px yellow)';
+ ctx.fillRect(20, 100, 50, 50);
+ ctx.filter = 'drop-shadow(10px 10px 15px cyan)';
+ ctx.fillRect(100, 100, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html
new file mode 100644
index 0000000000..294a219b70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior when both shadow properties and filters are used at the
+ same time is that the filter is applied to the elements drawn and the shadow
+ properties create another shadow that includes even shadows of the
+ filter-generated shadows.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(40, 40, 50, 50);
+ ctx.fillRect(30, 30, 50, 50);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.fillStyle = 'black';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html
new file mode 100644
index 0000000000..2057b95c3e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-and-properties.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-shadow-and-properties-expected.html"/>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior when both shadow properties and filters are used at the
+ same time is that the filter is applied to the elements drawn and the shadow
+ properties create another shadow that includes even shadows of the
+ filter-generated shadows.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.shadowColor = 'cyan';
+ ctx.shadowOffsetX = 20;
+ ctx.shadowOffsetY = 20;
+ ctx.filter = 'drop-shadow(10px 10px 0 red)';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html
new file mode 100644
index 0000000000..04bc6392cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior of filter-generated shadows is tested against
+ a drawing using only rectangles that draws the shadows manually.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 50, 50);
+ ctx.fillStyle = 'black';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html
new file mode 100644
index 0000000000..ddc6c89ee5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-filter-shadow.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-filter-shadow-expected.html"/>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ /*
+ The expected behavior of filter-generated shadows is tested against
+ a drawing using only rectangles that draws the shadows manually.
+ */
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'drop-shadow(10px 10px 0 red)';
+ ctx.fillRect(10, 10, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html
new file mode 100644
index 0000000000..6d7bbcd03d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-globalAlpha.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-14000">
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.globalAlpha = 0.75;
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(10, 10, 50, 50);
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(70, 10, 50, 50);
+ ctx.globalAlpha = 0.25;
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(10, 70, 50, 50);
+ ctx.globalAlpha = 0;
+ ctx.fillStyle = 'chocolate';
+ ctx.fillRect(70, 70, 50, 50);
+
+ ctx.globalAlpha = 0.8;
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 150, 50, 50);
+ ctx.globalAlpha = 0.6;
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 150, 50, 50);
+ ctx.globalAlpha = 0.4;
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(30, 150, 50, 50);
+ ctx.globalAlpha = 0.2;
+ ctx.fillStyle = 'green';
+ ctx.fillRect(40, 150, 50, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html
new file mode 100644
index 0000000000..3eb7581981
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes-expected.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<body>
+</body>
+<script>
+ /*
+ Compare how the opacity is handled in different blend modes when setting its
+ value with filters or with properties.
+ */
+
+ function drawSquares(canvasId, x, y, compositeOperation) {
+ var canvas = document.getElementById(canvasId);
+ var ctx = canvas.getContext('2d');
+ canvas.style.position = 'absolute';
+ canvas.style.left = `${x}px`;
+ canvas.style.top = `${y}px`;
+
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.globalAlpha = 1.0;
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 200, 60);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.globalAlpha = 0.7;
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.globalCompositeOperation = compositeOperation;
+ ctx.globalAlpha = 0.5;
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(25, 25, 50, 50);
+ }
+
+ // Fomatted in the same matrix as the drawn elements.
+ var compositeOperations =
+ ['source-over', 'source-in', 'source-out', 'source-atop','destination-over',
+ 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'copy',
+ 'xor', 'multiply', 'screen', 'overlay', 'darken',
+ 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
+ 'difference', 'exclusion', 'hue', 'saturation', 'color',
+ 'luminosity'];
+
+ for (var i = 0; i < compositeOperations.length; i++){
+ var canvas = document.createElement('canvas');
+ canvas.id = `canvas-${i}`;
+ document.body.appendChild(canvas);
+ drawSquares(canvas.id, (i%5)*300, Math.floor(i/5)*300,
+ compositeOperations[i]);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html
new file mode 100644
index 0000000000..a2d513eb62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-blend-modes.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<link rel="match" href="canvas-opacity-blend-modes-expected.html"/>
+<meta name="fuzzy" content="maxDifference=0-2; totalPixels=0-390000">
+<body>
+</body>
+<script>
+ /*
+ Compare how the opacity is handled in different blend modes when setting its
+ value with filters or with properties.
+ */
+
+ function drawSquares(canvasId, x, y, compositeOperation) {
+ var canvas = document.getElementById(canvasId);
+ var ctx = canvas.getContext('2d');
+ canvas.style.position = 'absolute';
+ canvas.style.left = `${x}px`;
+ canvas.style.top = `${y}px`;
+
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.filter = 'opacity(100%)';
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 200, 60);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.filter = 'opacity(70%)';
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.globalCompositeOperation = compositeOperation;
+ ctx.filter = 'opacity(50%)';
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(25, 25, 50, 50);
+ }
+
+ // Fomatted in the same matrix as the drawn elements.
+ var compositeOperations =
+ ['source-over', 'source-in', 'source-out', 'source-atop','destination-over',
+ 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'copy',
+ 'xor', 'multiply', 'screen', 'overlay', 'darken',
+ 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
+ 'difference', 'exclusion', 'hue', 'saturation', 'color',
+ 'luminosity'];
+
+ for (var i = 0; i < compositeOperations.length; i++){
+ var canvas = document.createElement('canvas');
+ canvas.id = `canvas-${i}`;
+ document.body.appendChild(canvas);
+ drawSquares(canvas.id, (i%5)*300, Math.floor(i/5)*300,
+ compositeOperations[i]);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html
new file mode 100644
index 0000000000..caf6b53ce3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/canvas-opacity-expected.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<body>
+ <div id="sq-1"></div>
+ <div id="sq-2"></div>
+ <div id="sq-3"></div>
+ <div id="sq-4"></div>
+ <div id="sq-5"></div>
+ <div id="sq-6"></div>
+ <div id="sq-7"></div>
+ <div id="sq-8"></div>
+</body>
+<style>
+ div{
+ width: 50px;
+ height: 50px;
+ position: absolute;
+ }
+ #sq-1{
+ background-color: teal;
+ left: 18px;
+ top: 18px;
+ opacity: 0.75;
+ }
+ #sq-2{
+ background-color: magenta;
+ left: 78px;
+ top: 18px;
+ opacity: 0.5;
+ }
+ #sq-3{
+ background-color: orange;
+ left: 18px;
+ top: 78px;
+ opacity: 0.25;
+ }
+ #sq-4{
+ background-color: chocolate;
+ left: 78px;
+ top: 78px;
+ opacity: 0;
+ }
+ #sq-5{
+ background-color: cyan;
+ left: 18px;
+ top: 158px;
+ opacity: 0.8;
+ }
+ #sq-6{
+ background-color: red;
+ left: 28px;
+ top: 158px;
+ opacity: 0.6;
+ }
+ #sq-7{
+ background-color: yellow;
+ left: 38px;
+ top: 158px;
+ opacity: 0.4;
+ }
+ #sq-8{
+ background-color: green;
+ left: 48px;
+ top: 158px;
+ opacity: 0.2;
+ }
+</style>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html b/testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html
new file mode 100644
index 0000000000..f64379c792
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/svg-filter-crash.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script>
+ document.addEventListener('DOMContentLoaded', async () => {
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
+ const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter')
+ filter.setAttribute('id', 'id_0')
+ svg.appendChild(filter)
+ document.documentElement.appendChild(svg)
+ const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas')
+ const context = canvas.getContext('2d')
+ context.filter = 'url(#id_0) url(#id_0) sepia() url(#id_0)'
+ svg.setAttribute('style', 'display: inline-block;')
+ })
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html
new file mode 100644
index 0000000000..ae8911b2de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur-expected.html
@@ -0,0 +1,19 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = 'blur(2px)';
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(10,10,100,100);
+ ctx.filter = 'blur(5px)';
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(120, 10, 100, 100);
+ ctx.filter = 'blur(5px) blur(10px)';
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 120, 100, 100);
+ ctx.filter = 'none';
+ ctx.fillStyle = 'black';
+ ctx.fillRect(120, 120, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html
new file mode 100644
index 0000000000..9fe7ef120c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-blur.html
@@ -0,0 +1,24 @@
+<head>
+ <link rel="match" href="canvas-filter-object-blur-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ ctx.filter = new CanvasFilter({name: "gaussianBlur", stdDeviation: 2});
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(10,10,100,100);
+ ctx.filter = new CanvasFilter({name: "gaussianBlur", stdDeviation: 5});
+ ctx.fillStyle = 'magenta';
+ ctx.fillRect(120, 10, 100, 100);
+ ctx.filter = new CanvasFilter([
+ {name: "gaussianBlur", stdDeviation: 5},
+ {name: "gaussianBlur", stdDeviation: 10}]);
+ ctx.fillStyle = 'cyan';
+ ctx.fillRect(10, 120, 100, 100);
+ ctx.filter = 'none';
+ ctx.fillStyle = 'black';
+ ctx.fillRect(120, 120, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html
new file mode 100644
index 0000000000..a2351cbcf2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer-expected.html
@@ -0,0 +1,65 @@
+<body>
+ <canvas id="canvas" width="500" height="100"></canvas>
+ <svg width="0", height="0">
+ <defs>
+ <filter color-interpolation-filters='sRGB' id="Identity" filterUnits="objectBoundingBox"
+ x="0%" y="0%" width="100%" height="100%">
+ <feComponentTransfer>
+ <feFuncR type="identity"/>
+ <feFuncG type="identity"/>
+ <feFuncB type="identity"/>
+ <feFuncA type="identity"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Table">
+ <feComponentTransfer>
+ <feFuncR type="table" tableValues="0 2 0.5 1"/>
+ <feFuncG type="table" tableValues="1 -1 5 0"/>
+ <feFuncB type="table" tableValues="0 1 1 0"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Discrete">
+ <feComponentTransfer>
+ <feFuncR type="discrete" tableValues="0 2 0.5 1"/>
+ <feFuncG type="discrete" tableValues="1 -1 5 0"/>
+ <feFuncB type="discrete" tableValues="0 1 1 0"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Linear">
+ <feComponentTransfer>
+ <feFuncR type="linear" slope=".5" intercept=".25"/>
+ <feFuncG type="linear" slope="1.5" intercept="0"/>
+ <feFuncB type="linear" slope="-0.5" intercept=".5"/>
+ </feComponentTransfer>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="Gamma">
+ <feComponentTransfer>
+ <feFuncR type="gamma" amplitude="2" exponent="5" offset="-0.5"/>
+ <feFuncG type="gamma" amplitude="0.9" exponent="3" offset="0.3"/>
+ <feFuncB type="gamma" amplitude="1.1" exponent="1" offset="0.1"/>
+ </feComponentTransfer>
+ </filter>
+ </defs>
+ </svg>
+</body>
+<script type="text/javascript">
+ const ctx = document.getElementById("canvas").getContext("2d");
+
+ const grad = ctx.createLinearGradient(10, 0, 490, 0);
+ grad.addColorStop(0, "#f00");
+ grad.addColorStop(0.33, "#0f0");
+ grad.addColorStop(0.67, "#00f");
+ grad.addColorStop(1, "#000");
+ ctx.fillStyle = grad;
+
+ ctx.filter = "url('#Identity')";
+ ctx.fillRect(10, 10, 480, 10);
+ ctx.filter = "url('#Table')";
+ ctx.fillRect(10, 30, 480, 10);
+ ctx.filter = "url('#Discrete')";
+ ctx.fillRect(10, 50, 480, 10);
+ ctx.filter = "url('#Linear')";
+ ctx.fillRect(10, 70, 480, 10);
+ ctx.filter = "url('#Gamma')";
+ ctx.fillRect(10, 90, 480, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html
new file mode 100644
index 0000000000..47889c0db2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-component-transfer.html
@@ -0,0 +1,62 @@
+<head>
+ <link rel="match" href="canvas-filter-object-component-transfer-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="500" height="100"></canvas>
+</body>
+<script>
+ const ctx = document.getElementById("canvas").getContext("2d");
+
+ const grad = ctx.createLinearGradient(10, 0, 490, 0);
+ grad.addColorStop(0, "#f00");
+ grad.addColorStop(0.33, "#0f0");
+ grad.addColorStop(0.67, "#00f");
+ grad.addColorStop(1, "#000");
+ ctx.fillStyle = grad;
+
+ const identityFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "identity"},
+ funcG: {type: "identity"},
+ funcB: {type: "identity"},
+ funcA: {type: "identity"},
+ });
+ ctx.filter = identityFilter;
+ ctx.fillRect(10, 10, 480, 10);
+
+ const tableFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "table", tableValues: [0, 2, 0.5, 1]},
+ funcG: {type: "table", tableValues: [1, -1, 5, 0]},
+ funcB: {type: "table", tableValues: [0, 1, 1, 0]},
+ });
+ ctx.filter = tableFilter;
+ ctx.fillRect(10, 30, 480, 10);
+
+ const discreteFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "discrete", tableValues: [0, 2, 0.5, 1]},
+ funcG: {type: "discrete", tableValues: [1, -1, 5, 0]},
+ funcB: {type: "discrete", tableValues: [0, 1, 1, 0]},
+ });
+ ctx.filter = discreteFilter;
+ ctx.fillRect(10, 50, 480, 10);
+
+ const linearFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "linear", slope: 0.5, intercept: 0.25},
+ funcG: {type: "linear", slope: 1.5, intercept: 0},
+ funcB: {type: "linear", slope: -0.5, intercept: 0.5},
+ });
+ ctx.filter = linearFilter;
+ ctx.fillRect(10, 70, 480, 10);
+
+ const gammaFilter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "gamma", amplitude: 2, exponent: 5, offset: -0.5},
+ funcG: {type: "gamma", amplitude: 0.9, exponent: 3, offset: 0.3},
+ funcB: {type: "gamma", amplitude: 1.1, exponent: 1, offset: 0.1},
+ });
+ ctx.filter = gammaFilter;
+ ctx.fillRect(10, 90, 480, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html
new file mode 100644
index 0000000000..896a93542e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix-expected.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<style type="text/css">
+ canvas {
+ margin: 5px;
+ }
+</style>
+<body>
+ <svg width="0" height="0">
+ <filter color-interpolation-filters='sRGB' id="justKernel">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="preserveAlpha">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ preserveAlpha="true"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="target">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ targetX="2" targetY="2"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="divisor">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ divisor="3"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="bias">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ bias="0.5"/>
+ </filter>
+ <filter color-interpolation-filters='sRGB' id="edgeMode">
+ <feConvolveMatrix
+ kernelMatrix="3 0 0 0 0 0 0 0 -3"
+ edgeMode="wrap"/>
+ </filter>
+ </svg>
+</body>
+<script type="text/javascript">
+
+const filters = [
+ "url('#justKernel')",
+ "url('#preserveAlpha')",
+ "url('#target')",
+ "url('#divisor')",
+ "url('#bias')",
+ "url('#edgeMode')",
+];
+
+function draw(ctx) {
+ ctx.fillRect(0, 20, 120, 100);
+
+ ctx.beginPath();
+ ctx.arc(150, 70, 50, 0, 2*Math.PI);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(220, 20);
+ ctx.lineTo(170, 120);
+ ctx.lineTo(270, 120);
+ ctx.lineTo(220, 20);
+ ctx.fill();
+}
+
+for (f of filters) {
+ const canvas = document.createElement("canvas");
+ document.body.prepend(canvas);
+ const ctx = canvas.getContext("2d");
+ ctx.filter = "blur(0px)";
+ ctx.fillStyle = "rgba(0,255,0,0.5)";
+ draw(ctx);
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ ctx.filter = f;
+ draw(ctx);
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html
new file mode 100644
index 0000000000..1dfd602d13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<head>
+ <link rel="match" href="canvas-filter-object-convolve-matrix-expected.html">
+ <style type="text/css">
+ canvas {
+ margin: 5px;
+ }
+ </style>
+</head>
+<body>
+</body>
+<script>
+function makeConvolveFilter(options) {
+ const KERNEL_MATRIX = [
+ [3, 0, 0],
+ [0, 0, 0],
+ [0, 0, -3],
+ ];
+
+ options = Object.assign(options, {
+ kernelMatrix: KERNEL_MATRIX, name: "convolveMatrix"});
+ return new CanvasFilter(options);
+}
+
+const test_cases = [
+ {},
+ {preserveAlpha: true},
+ {targetX: 2, targetY: 2},
+ {divisor: 3},
+ {bias: 0.5},
+ {edgeMode: "wrap"}
+];
+
+function draw(ctx) {
+ ctx.fillRect(0, 20, 120, 100);
+
+ ctx.beginPath();
+ ctx.arc(150, 70, 50, 0, 2*Math.PI);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(220, 20);
+ ctx.lineTo(170, 120);
+ ctx.lineTo(270, 120);
+ ctx.lineTo(220, 20);
+ ctx.fill();
+}
+
+for (tc of test_cases) {
+ const canvas = document.createElement("canvas");
+ document.body.prepend(canvas);
+ const ctx = canvas.getContext("2d");
+ ctx.filter = "blur(0px)";
+ ctx.fillStyle = "rgba(0,255,0,0.5)";
+ draw(ctx);
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ ctx.filter = makeConvolveFilter(tc);
+ draw(ctx);
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html
new file mode 100644
index 0000000000..ff0eebe2e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html
@@ -0,0 +1,37 @@
+<body>
+ <svg style="display:none">>
+ <filter id="base">
+ <feTurbulence baseFrequency="0.025"/>
+ </filter>
+ <filter id="base2d">
+ <feTurbulence baseFrequency="0.025, 0.1"/>
+ </filter>
+ <filter id="highFrequency">
+ <feTurbulence baseFrequency="0.05"/>
+ </filter>
+ <filter id="seed">
+ <feTurbulence baseFrequency="0.025" seed="100"/>
+ </filter>
+ <filter id="numOctaves">
+ <feTurbulence baseFrequency="0.025" numOctaves="2"/>
+ </filter>
+ <filter id="empty">
+ <feTurbulence/>
+ </filter>
+ <filter id="fractalNoise">
+ <feTurbulence baseFrequency="0.025" type="fractalNoise"/>
+ </filter>
+ <filter id="stitchTiles">
+ <feTurbulence baseFrequency="0.025" stitchTiles="noStitch"/>
+ </filter>
+</body>
+<script>
+ testCases = document.getElementsByTagName("filter");
+ for (tc of testCases) {
+ const canvas = document.createElement("canvas");
+ document.body.appendChild(canvas);
+ const ctx = canvas.getContext("2d");
+ ctx.filter = `url(#${tc.id})`;
+ ctx.fillRect(0, 0, 1, 1);
+ }
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html
new file mode 100644
index 0000000000..b5b494825e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html
@@ -0,0 +1,26 @@
+<head>
+ <link rel="match" href="canvas-filter-object-blur-expected.html">
+</head>
+<body>
+</body>
+<script>
+ const testCases = [
+ {baseFrequency: 0.025},
+ {baseFrequency: [0.025, 0.1]},
+ {baseFrequency: 0.05},
+ {baseFrequency: 0.025, seed: 100},
+ {baseFrequency: 0.025, numOctaves: 2},
+ {},
+ {baseFrequency: 0.025, type: "fractalNoise"},
+ {baseFrequency: 0.025, stitchTiles: "stitch"},
+ ]
+
+ for (tc of testCases) {
+ const canvas = document.createElement("canvas");
+ document.body.appendChild(canvas);
+ const ctx = canvas.getContext("2d");
+ const filterOptions = {...{name: "turbulence"}, ...tc};
+ ctx.filter = new CanvasFilter(filterOptions);
+ ctx.fillRect(0, 0, 1, 1);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html
new file mode 100644
index 0000000000..f043b0e762
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion-expected.html
@@ -0,0 +1,30 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // preserveAlpha for convolveMatrix is the only boolean so far implemented
+ function drawWithConvolveFilter(x, y, preserveAlphaValue) {
+ ctx.filter = new CanvasFilter({
+ name: "convolveMatrix",
+ kernelMatrix: [[1, 0], [0, 1]],
+ preserveAlpha: preserveAlphaValue,
+ });
+ ctx.fillRect(x, y, 30, 30);
+ }
+
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ let x = 10;
+ let y = 10;
+ for (var i = 0; i < 6; i++) {
+ drawWithConvolveFilter(x, y, true);
+ x += 40;
+ }
+ y = 50;
+ x = 10;
+ for (var i = 0; i < 5; i++) {
+ drawWithConvolveFilter(x, y, false);
+ x += 40;
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html
new file mode 100644
index 0000000000..97ade79f37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-boolean-conversion.html
@@ -0,0 +1,58 @@
+<head>
+ <link rel="match" href="canvas-filter-boolean-conversion-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ // Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
+ // as input to the CanvasFilter resolver when a bool is the intended result.
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // preserveAlpha for convolveMatrix is the only boolean so far implemented
+ function drawWithConvolveFilter(x, y, preserveAlphaValue) {
+ ctx.filter = new CanvasFilter({
+ name: "convolveMatrix",
+ kernelMatrix: [[1, 0], [0, 1]],
+ preserveAlpha: preserveAlphaValue,
+ });
+ ctx.fillRect(x, y, 30, 30);
+ }
+
+ const trueTestCases = [
+ true,
+ { valueOf() { return false; }},
+ "foo",
+ 1,
+ {},
+ []
+ ];
+
+ const falseTestCases = [
+ false,
+ "",
+ 0,
+ null,
+ undefined,
+ ];
+
+ ctx.fillStyle = "rgba(255,0,255,0.5)";
+ let x = 10;
+ let y = 10;
+ for (tc of trueTestCases) {
+ drawWithConvolveFilter(x, y, tc);
+ x += 40;
+ }
+ y = 50;
+ x = 10;
+ for (tc of falseTestCases) {
+ drawWithConvolveFilter(x, y, tc);
+ x += 40;
+ }
+
+ ctx.filter = new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "discrete", tableValues: 0.5},
+ });
+ ctx.fillRect(10, 10, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html
new file mode 100644
index 0000000000..8b4262ed04
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion-expected.html
@@ -0,0 +1,26 @@
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ var ctx = document.getElementById('canvas').getContext('2d');
+ // Null and False both evaluate to zero
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(50, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
+ ctx.fillRect(90, 10, 30, 30);
+ // True evaluates to one
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 1});
+ ctx.fillRect(130, 10, 30, 30);
+ // String, Number and Object should all work
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(10, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(50, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(90, 50, 30, 30);
+ // Valid sequence
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(130, 50, 30, 30);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html
new file mode 100644
index 0000000000..c742633224
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-long-conversion.html
@@ -0,0 +1,35 @@
+<head>
+ <link rel="match" href="canvas-filter-long-conversion-expected.html">
+</head>
+<body>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+ // Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
+ // as input to the CanvasFilter resolver when a long is the intended result.
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // Null, False and [] evaluate to zero
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: null});
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: false});
+ ctx.fillRect(50, 10, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: []});
+ ctx.fillRect(90, 10, 30, 30);
+ // True evaluates to one
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: true});
+ ctx.fillRect(130, 10, 30, 30);
+ // String, Number and Object should all work
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "5"});
+ ctx.fillRect(10, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
+ ctx.fillRect(50, 50, 30, 30);
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: { valueOf() { return 5; }}});
+ ctx.fillRect(90, 50, 30, 30);
+ // Valid sequence
+ ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [5]});
+ ctx.fillRect(130, 50, 30, 30);
+
+ // Undefined and other inputs that throw exceptions are tested in:
+ // html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html
new file mode 100644
index 0000000000..d48627867e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/idl-conversions/canvas-filter-sequence-conversion.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>Canvas test: canvas-filter-sequence-conversion</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>canvas-filter-sequence-conversion</h1>
+<p class="desc">Test converting types into sequences</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test pixels on CanvasFilter() various inputs to tableValues (which is a sequence)");
+_addTest(function(canvas, ctx) {
+
+ // Inputs to parameters that are expecting sequence<long>. Results are either the value of the
+ // red pixel drawing using the resultant filter or that we expect this input to throw an error.
+ const testCases = [
+ {input: [], result: 0},
+ {input: [0.5], result: 127},
+ {input: ["0.5"], result: 127},
+ {input: 1, result: "throws"},
+ {input: {}, result: "throws"},
+ {input: false, result: "throws"},
+ {input: true, result: "throws"},
+ {input: NaN, result: "throws"},
+ {input: { valueOf() { return [1]; }}, result: "throws"},
+ ];
+
+ // A simple filter that just overrides the red channel if successful.
+ function makeFilter(value) {
+ return new CanvasFilter({
+ name: "componentTransfer",
+ funcR: {type: "table", tableValues: value}
+ });
+ }
+
+ for (const tc of testCases) {
+ if (tc.result === "throws") {
+ assert_throws_js(TypeError, function(){ makeFilter(tc.input) });
+ } else {
+ ctx.reset();
+ ctx.filter = makeFilter(tc.input);
+ ctx.fillRect(0, 0, 100, 100);
+ _assertPixelApprox(canvas, 5, 5, tc.result,0,0,255, 2);
+ }
+ }
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/image-smoothing/imagesmoothing.html b/testing/web-platform/tests/html/canvas/element/manual/image-smoothing/imagesmoothing.html
new file mode 100644
index 0000000000..1a86a8f201
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/image-smoothing/imagesmoothing.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext2D imageSmoothingEnabled test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing">
+<script>
+function createTestImage() {
+ var image = document.createElement('canvas');
+ var imgctx = image.getContext('2d');
+ imgctx.fillStyle = "#F00";
+ imgctx.fillRect(0, 0, 2, 2);
+ imgctx.fillStyle = "#0F0";
+ imgctx.fillRect(0, 0, 1, 1);
+ return image;
+}
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ assert_true(ctx.imageSmoothingEnabled);
+}, "When the canvas context is created, imageSmoothingEnabled must be set to true.");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ ctx.imageSmoothingEnabled = false;
+ assert_false(ctx.imageSmoothingEnabled);
+}, "On getting imageSmoothingEnabled, the user agent must return the last value it was set to.");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ var image = createTestImage();
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_not_equals(pixels[0], 0);
+ assert_not_equals(pixels[1], 255);
+}, "Test that image smoothing is actually on by default and just the attribute value.");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ ctx.imageSmoothingEnabled = true;
+ var image = createTestImage();
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_not_equals(pixels[0], 0);
+ assert_not_equals(pixels[1], 255);
+}, "Test that image smoothing works when imageSmoothingEnabled is set to true");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with drawImage().");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.fillStyle = ctx.createPattern(image, 'repeat');
+ ctx.fillRect(0, 0, 10, 10);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with fillRect and createPattern().");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.fillStyle = ctx.createPattern(image, 'repeat');
+ ctx.scale(10, 10);
+ ctx.rect(0, 0, 10, 10);
+ ctx.fill();
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with fill() and createPattern().");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ var image = createTestImage();
+ ctx.strokeStyle = ctx.createPattern(image, 'repeat');
+ ctx.lineWidth = 5;
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.stroke();
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with stroke() and createPattern().");
+
+test(function() {
+ var repaints = 5;
+ var ctx = document.createElement('canvas').getContext('2d');
+
+ function draw() {
+ ctx.clearRect(0, 0, 10, 10);
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+ }
+
+ while (repaints > 0) {
+ draw();
+ repaints = repaints - 1;
+ }
+
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) still works after repaints.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-ImageBitmap-close.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-ImageBitmap-close.html
new file mode 100644
index 0000000000..fca8274528
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-ImageBitmap-close.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<body>
+ <p>Tests that the close method of ImageBitmap does dispose the image data.</p>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+promise_test(function(t) {
+ var worker = new Worker('worker-onmessage-noop.js');
+
+ var imgHeight = 10;
+ var imgWidth = 10;
+ var imageData = new ImageData(10, 10);
+ var bitmap;
+ var ctx;
+ return createImageBitmap(imageData).then(imageBitmap => {
+ bitmap = imageBitmap;
+ assert_equals(bitmap.width, imgWidth, "bitmap.width = 10");
+ assert_equals(bitmap.height, imgWidth, "bitmap.height = 10");
+
+ // Apply structured clone to the bitmap, nothing should be changed
+ worker.postMessage({data: bitmap});
+ assert_equals(bitmap.width, imgWidth, "bitmap.width = 10");
+ assert_equals(bitmap.height, imgWidth, "bitmap.height = 10");
+
+ // After calling close, the image data associated with the bitmap should no longer exist
+ bitmap.close();
+ assert_equals(bitmap.width, 0, "bitmap.width = 0");
+ assert_equals(bitmap.height, 0, "bitmap.height = 0");
+
+ var canvas = document.createElement("canvas");
+ canvas.width = imgWidth;
+ canvas.height = imgHeight;
+ ctx = canvas.getContext("2d");
+ assert_throws_dom("InvalidStateError", function() { ctx.drawImage(bitmap, 0, 0); });
+
+ // Try to apply structured clone to an already closed bitmap
+ try {
+ worker.postMessage({data: bitmap});
+ throw new Error("Apply clone to an closed bitmap should be rejected");
+ }
+ catch(ex) {
+ // Apply structured clone to an already closed bitmap is rejected as expected.
+ }
+
+ // Try to apply transferring to an already closed bitmap
+ try {
+ worker.postMessage({data: bitmap}, [bitmap]);
+ throw new Error("Apply transferring to an closed bitmap should be rejected");
+ } catch(ex) {
+ // Apply structured clone to an already closed bitmap is rejected as expected.
+ }
+
+ // Calling createImageBitmap from a closed bitmap should be rejected
+ return createImageBitmap(bitmap).then(function() {
+ throw new Error("createImageBitmap from a closed bitmap should be rejected");
+ }, ex => {
+ // Calling createImageBitmap from a closed ImageBitmap is rejected as expected.
+ });
+ }).then(() => {
+ // Call close to a already closed bitmap should be noop.
+ bitmap.close();
+ assert_equals(bitmap.width, 0, "bitmap.height = 0");
+ assert_equals(bitmap.height, 0, "bitmap.height = 0");
+
+ return createImageBitmap(imageData).then(imageBitmap => {
+ bitmap = imageBitmap;
+ assert_equals(bitmap.width, imgWidth, "bitmap.width = 10");
+ assert_equals(bitmap.height, imgWidth, "bitmap.height = 10");
+
+ // Transfer the bitmap to a worker
+ worker.postMessage({data: bitmap}, [bitmap]);
+
+ // After transferring, the bitmap is neutered.
+ assert_equals(bitmap.width, 0, "bitmap.height = 0");
+ assert_equals(bitmap.height, 0, "bitmap.height = 0");
+
+ // Calling close to a neutered bitmap should be noop.
+ bitmap.close();
+ assert_equals(bitmap.width, 0, "bitmap.height = 0");
+ assert_equals(bitmap.height, 0, "bitmap.height = 0");
+
+ });
+ }).catch(function(ex) {
+ throw new Error("No exception should be thrown.");
+ })
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html
new file mode 100644
index 0000000000..782c7e130c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html
@@ -0,0 +1,170 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function checkNoCrop(imageBitmap)
+{
+ var canvas = document.createElement("canvas");
+ canvas.width = 50;
+ canvas.height = 50;
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(imageBitmap, 0, 0);
+ var d = ctx.getImageData(0, 0, 1, 1).data;
+ assert_array_equals(d, [255, 0, 0, 255], "This pixel should be red.");
+ d = ctx.getImageData(39, 0, 1, 1).data;
+ assert_array_equals(d, [0, 255, 0, 255], "This pixel should be green.");
+ d = ctx.getImageData(0, 39, 1, 1).data;
+ assert_array_equals(d, [0, 0, 255, 255], "This pixel should be blue.");
+ d = ctx.getImageData(39, 39, 1, 1).data;
+ assert_array_equals(d, [0, 0, 0, 255], "This pixel should be black.");
+ d = ctx.getImageData(41, 41, 1, 1).data;
+ assert_array_equals(d, [0, 0, 0, 0], "This pixel should be transparent black.");
+}
+
+function checkCrop(imageBitmap)
+{
+ var canvas = document.createElement("canvas");
+ canvas.width = 50;
+ canvas.height = 50;
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(imageBitmap, 0, 0);
+ var d = ctx.getImageData(0, 0, 1, 1).data;
+ assert_array_equals(d, [255, 0, 0, 255], "This pixel should be red.");
+ d = ctx.getImageData(19, 0, 1, 1).data;
+ assert_array_equals(d, [0, 255, 0, 255], "This pixel should be green.");
+ d = ctx.getImageData(0, 19, 1, 1).data;
+ assert_array_equals(d, [0, 0, 255, 255], "This pixel should be blue.");
+ d = ctx.getImageData(19, 19, 1, 1).data;
+ assert_array_equals(d, [0, 0, 0, 255], "This pixel should be black.");
+ d = ctx.getImageData(21, 21, 1, 1).data;
+ assert_array_equals(d, [0, 0, 0, 0], "This pixel should be transparent black.");
+}
+
+function compareBitmaps(bitmap1, bitmap2)
+{
+ var canvas1 = document.createElement("canvas");
+ var canvas2 = document.createElement("canvas");
+ canvas1.width = 50;
+ canvas1.height = 50;
+ canvas2.width = 50;
+ canvas2.height = 50;
+ var ctx1 = canvas1.getContext("2d");
+ var ctx2 = canvas2.getContext("2d");
+ ctx1.clearRect(0, 0, canvas1.width, canvas1.height);
+ ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
+ ctx1.drawImage(bitmap1, 0, 0);
+ ctx2.drawImage(bitmap2, 0, 0);
+ var data1 = ctx1.getImageData(0, 0, 50, 50).data;
+ var data2 = ctx2.getImageData(0, 0, 50, 50).data;
+ var dataMatched = true;
+ for (var i = 0; i < data1.length; i++) {
+ if (data1[i] != data2[i]) {
+ dataMatched = false;
+ break;
+ }
+ }
+ assert_false(dataMatched);
+}
+
+function testImageBitmap(source)
+{
+ return Promise.all([
+ createImageBitmap(source, {resizeWidth: 40, resizeHeight: 40, resizeQuality: "high"}),
+ createImageBitmap(source, {resizeWidth: 40, resizeHeight: 40, resizeQuality: "medium"}),
+ createImageBitmap(source, {resizeWidth: 40, resizeHeight: 40, resizeQuality: "low"}),
+ createImageBitmap(source, {resizeWidth: 40, resizeHeight: 40, resizeQuality: "pixelated"}),
+ createImageBitmap(source, 5, 5, 10, 10, {resizeWidth: 20, resizeHeight: 20, resizeQuality: "high"}),
+ createImageBitmap(source, 5, 5, 10, 10, {resizeWidth: 20, resizeHeight: 20, resizeQuality: "medium"}),
+ createImageBitmap(source, 5, 5, 10, 10, {resizeWidth: 20, resizeHeight: 20, resizeQuality: "low"}),
+ createImageBitmap(source, 5, 5, 10, 10, {resizeWidth: 20, resizeHeight: 20, resizeQuality: "pixelated"}),
+ ]).then(([noCropHigh, noCropMedium, noCropLow, noCropPixelated, cropHigh, cropMedium, cropLow, cropPixelated]) => {
+ checkNoCrop(noCropHigh);
+ checkNoCrop(noCropMedium);
+ checkNoCrop(noCropLow);
+ checkNoCrop(noCropPixelated);
+ checkCrop(cropHigh);
+ checkCrop(cropMedium);
+ checkCrop(cropLow);
+ checkCrop(cropPixelated);
+ // Brute-force comparison among all bitmaps is too expensive
+ compareBitmaps(noCropHigh, noCropMedium);
+ compareBitmaps(noCropLow, noCropPixelated);
+ compareBitmaps(cropHigh, cropMedium);
+ compareBitmaps(cropLow, cropPixelated);
+ });
+}
+
+function initializeTestCanvas()
+{
+ var testCanvas = document.createElement("canvas");
+ testCanvas.width = 20;
+ testCanvas.height = 20;
+ var testCtx = testCanvas.getContext("2d");
+ testCtx.fillStyle = "rgb(255, 0, 0)";
+ testCtx.fillRect(0, 0, 10, 10);
+ testCtx.fillStyle = "rgb(0, 255, 0)";
+ testCtx.fillRect(10, 0, 10, 10);
+ testCtx.fillStyle = "rgb(0, 0, 255)";
+ testCtx.fillRect(0, 10, 10, 10);
+ testCtx.fillStyle = "rgb(0, 0, 0)";
+ testCtx.fillRect(10, 10, 10, 10);
+ return testCanvas;
+}
+
+// Blob
+promise_test(function() {
+ return new Promise((resolve, reject) => {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/pattern.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ }).then(testImageBitmap);
+}, 'createImageBitmap from a Blob with resize option.');
+
+// HTMLCanvasElement
+promise_test(function() {
+ var testCanvas = initializeTestCanvas();
+ return testImageBitmap(testCanvas);
+}, 'createImageBitmap from a HTMLCanvasElement with resize option.');
+
+// HTMLImageElement
+promise_test(function() {
+ return new Promise((resolve, reject) => {
+ var image = new Image();
+ image.onload = function() {
+ resolve(image);
+ }
+ image.src = '/images/pattern.png'
+ }).then(testImageBitmap);
+}, 'createImageBitmap from a HTMLImageElement with resize option.');
+
+// HTMLImageElement of svg with no specified size
+promise_test(function() {
+ return new Promise((resolve, reject) => {
+ var image = new Image();
+ image.onload = function() {
+ resolve(image);
+ }
+ image.src = '/images/pattern-nosize.svg'
+ }).then(testImageBitmap);
+}, 'createImageBitmap from a HTMLImageElement of svg with no specified size with resize option.');
+
+// ImageBitmap
+promise_test(function() {
+ var testCanvas = initializeTestCanvas();
+ return createImageBitmap(testCanvas).then(testImageBitmap);
+}, 'createImageBitmap from an ImageBitmap with resize option.');
+
+// ImageData
+promise_test(function() {
+ var canvas = initializeTestCanvas();
+ var ctx = canvas.getContext("2d");
+ var data = ctx.getImageData(0, 0, 20, 20);
+ return testImageBitmap(data);
+}, 'createImageBitmap from an ImageData with resize option.');
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-video-resize.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-video-resize.html
new file mode 100644
index 0000000000..d48d9e80ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-video-resize.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<script>
+function createNewCanvas(width, height)
+{
+ var canvas = document.createElement("canvas");
+ canvas.width = width;
+ canvas.height = height;
+ var ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0, width, height);
+ return ctx;
+}
+
+function checkLowResult(imageBitmap, bw, bh, video, sx, sy, sw, sh)
+{
+ var ctx1 = createNewCanvas(bw, bh);
+ var ctx2 = createNewCanvas(bw, bh);
+ ctx1.drawImage(imageBitmap, 0, 0);
+ ctx2.drawImage(video, sx, sy, sw, sh, 0, 0, bw, bh);
+ var data1 = ctx1.getImageData(0, 0, bw, bh).data;
+ var data2 = ctx2.getImageData(0, 0, bw, bh).data;
+ var dataMatched = true;
+ for (var i = 0; i < data1.length; i++) {
+ // data1[i] is strictly the same as data2[i] on software rendering.
+ // But on GPU, the difference could be quite significant.
+ if (Math.abs(data1[i] - data2[i]) > 33) {
+ dataMatched = false;
+ break;
+ }
+ }
+ assert_true(dataMatched);
+}
+
+function generateTest()
+{
+ bitmapWidth = video.videoWidth/2;
+ bitmapHeight = video.videoHeight/2;
+ return Promise.all([
+ createImageBitmap(video, {resizeWidth: bitmapWidth, resizeHeight: bitmapHeight, resizeQuality: "low"}),
+ createImageBitmap(video, 10, 10, bitmapWidth, bitmapHeight, {resizeWidth: bitmapWidth, resizeHeight: bitmapHeight, resizeQuality: "low"}),
+ ]).then(t.step_func_done(([noCropLow, cropLow]) => {
+ checkLowResult(noCropLow, bitmapWidth, bitmapHeight, video, 0, 0, video.videoWidth, video.videoHeight);
+ checkLowResult(cropLow, bitmapWidth, bitmapHeight, video, 10, 10, bitmapWidth, bitmapHeight);
+ }), t.step_func_done(function() {
+ assert_true(false, 'Promise rejected');
+ }));
+}
+
+var t = async_test('createImageBitmap(HTMLVideoElement) with resize option');
+
+// HTMLVideoElement
+var video = document.createElement("video");
+video.preload = "auto";
+if (video.requestVideoFrameCallback) {
+ video.requestVideoFrameCallback(t.step_func(() => generateTest()));
+} else {
+ video.oncanplaythrough = t.step_func(() => generateTest());
+}
+video.src = getVideoURI("/media/counting");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/common.sub.js b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/common.sub.js
new file mode 100644
index 0000000000..1889035202
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/common.sub.js
@@ -0,0 +1,168 @@
+function makeCanvas() {
+ return new Promise(resolve => {
+ var testCanvas = document.createElement("canvas");
+ testCanvas.width = 20;
+ testCanvas.height = 20;
+ var testCtx = testCanvas.getContext("2d");
+ testCtx.fillStyle = "rgb(255, 0, 0)";
+ testCtx.fillRect(0, 0, 10, 10);
+ testCtx.fillStyle = "rgb(0, 255, 0)";
+ testCtx.fillRect(10, 0, 10, 10);
+ testCtx.fillStyle = "rgb(0, 0, 255)";
+ testCtx.fillRect(0, 10, 10, 10);
+ testCtx.fillStyle = "rgb(0, 0, 0)";
+ testCtx.fillRect(10, 10, 10, 10);
+ resolve(testCanvas);
+ });
+}
+
+function makeOffscreenCanvas() {
+ return new Promise(resolve => {
+ let canvas = new OffscreenCanvas(20, 20);
+ var testCtx = canvas.getContext("2d");
+ testCtx.fillStyle = "rgb(255, 0, 0)";
+ testCtx.fillRect(0, 0, 10, 10);
+ testCtx.fillStyle = "rgb(0, 255, 0)";
+ testCtx.fillRect(10, 0, 10, 10);
+ testCtx.fillStyle = "rgb(0, 0, 255)";
+ testCtx.fillRect(0, 10, 10, 10);
+ testCtx.fillStyle = "rgb(0, 0, 0)";
+ testCtx.fillRect(10, 10, 10, 10);
+ resolve(canvas);
+ });
+}
+
+var imageBitmapVideoPromise = new Promise(function(resolve, reject) {
+ var video = document.createElement("video");
+ video.oncanplaythrough = function() {
+ resolve(video);
+ };
+ video.onerror = reject;
+
+ // preload=auto is required to ensure a frame is available once
+ // canplaythrough is fired. The default of preload=metadata does not
+ // gaurantee this.
+ video.preload = "auto";
+ video.src = getVideoURI("/images/pattern");
+
+ // Prevent WebKit from garbage collecting event handlers.
+ window._video = video;
+});
+
+function makeVideo() {
+ return imageBitmapVideoPromise;
+}
+
+var imageBitmapDataUrlVideoPromise = fetch(getVideoURI("/images/pattern"))
+ .then(response => Promise.all([response.headers.get("Content-Type"), response.arrayBuffer()]))
+ .then(([type, data]) => {
+ return new Promise(function(resolve, reject) {
+ var video = document.createElement("video");
+ video.oncanplaythrough = function() {
+ resolve(video);
+ };
+ video.onerror = reject;
+
+ var encoded = btoa(String.fromCodePoint(...new Uint8Array(data)));
+ var dataUrl = `data:${type};base64,${encoded}`;
+
+ // preload=auto is required to ensure a frame is available once
+ // canplaythrough is fired. The default of preload=metadata does not
+ // gaurantee this.
+ video.preload = "auto";
+ video.src = dataUrl;
+
+ // Prevent WebKit from garbage collecting event handlers.
+ window._dataVideo = video;
+ });
+ });
+
+function makeDataUrlVideo() {
+ return imageBitmapDataUrlVideoPromise;
+}
+
+function makeMakeHTMLImage(src) {
+ return function() {
+ return new Promise((resolve, reject) => {
+ var img = new Image();
+ img.onload = function() {
+ resolve(img);
+ };
+ img.onerror = reject;
+ img.src = src;
+ });
+ }
+}
+
+function makeMakeSVGImage(src) {
+ return function() {
+ return new Promise((resolve, reject) => {
+ var image = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ image.onload = () => resolve(image);
+ image.onerror = reject;
+ image.setAttribute("externalResourcesRequired", "true");
+ image.setAttributeNS("http://www.w3.org/1999/xlink", 'xlink:href', src);
+ document.body.appendChild(image);
+ });
+ }
+}
+
+function makeImageData() {
+ return new Promise(function(resolve, reject) {
+ var width = 20, height = 20;
+ var imgData = new ImageData(width, height);
+ for (var i = 0; i < width * height * 4; i += 4) {
+ imgData.data[i] = 0;
+ imgData.data[i + 1] = 0;
+ imgData.data[i + 2] = 0;
+ imgData.data[i + 3] = 255; //alpha channel: 255
+ }
+ var halfWidth = width / 2;
+ var halfHeight = height / 2;
+ // initialize to R, G, B, Black, with each one 10*10 pixels
+ for (var i = 0; i < halfHeight; i++)
+ for (var j = 0; j < halfWidth; j++)
+ imgData.data[i * width * 4 + j * 4] = 255;
+ for (var i = 0; i < halfHeight; i++)
+ for (var j = halfWidth; j < width; j++)
+ imgData.data[i * width * 4 + j * 4 + 1] = 255;
+ for (var i = halfHeight; i < height; i++)
+ for (var j = 0; j < halfWidth; j++)
+ imgData.data[i * width * 4 + j * 4 + 2] = 255;
+ resolve(imgData);
+ });
+}
+
+function makeImageBitmap() {
+ return makeCanvas().then(canvas => {
+ return createImageBitmap(canvas);
+ });
+}
+
+function makeBlob(src) {
+ return function () {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", src);
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ }
+}
+
+var imageSourceTypes = [
+ { name: 'an HTMLCanvasElement', factory: makeCanvas },
+ { name: 'an HTMLVideoElement', factory: makeVideo },
+ { name: 'an HTMLVideoElement from a data URL', factory: makeDataUrlVideo },
+ { name: 'a bitmap HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.png") },
+ { name: 'a vector HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.svg") },
+ { name: 'a bitmap SVGImageElement', factory: makeMakeSVGImage("/images/pattern.png") },
+ { name: 'a vector SVGImageElement', factory: makeMakeSVGImage("/images/pattern.svg") },
+ { name: 'an OffscreenCanvas', factory: makeOffscreenCanvas },
+ { name: 'an ImageData', factory: makeImageData },
+ { name: 'an ImageBitmap', factory: makeImageBitmap },
+ { name: 'a Blob', factory: makeBlob("/images/pattern.png") },
+];
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-blob-invalidtype.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-blob-invalidtype.html
new file mode 100644
index 0000000000..23af96408a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-blob-invalidtype.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<title>createImageBitmap: blob with wrong mime type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<script>
+promise_test(t => {
+ // Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
+ const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
+ "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
+
+ let bytes = new Array(IMAGE.length);
+ for (let i = 0; i < IMAGE.length; i++) {
+ bytes[i] = IMAGE.charCodeAt(i);
+ }
+
+ let blob = new Blob([new Uint8Array(bytes)], { type: "text/html"});
+
+ return window.createImageBitmap(blob)
+ .then(imageBitmap => {
+ assert_true(true, "Image created!");
+ assert_equals(imageBitmap.width, 1, "Image is 1x1");
+ assert_equals(imageBitmap.height, 1, "Image is 1x1");
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html
new file mode 100644
index 0000000000..a2dcf0cc0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-bounds.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<title>createImageBitmap: clipping to the bitmap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<div id="results"></div>
+<script>
+const color = 204;
+function testClip( name, sx, sy, sw, sh, expectedColors, expectedWidth, expectedHeight ) {
+ promise_test(function(t) {
+ return new Promise(function(resolve, reject) {
+ const image = new Image();
+ image.onload = function() { resolve(image); };
+ image.onerror = function() { reject(); };
+ image.src = "/images/green-16x16.png";
+ }).then(function(image) {
+ return createImageBitmap(image, sx, sy, sw, sh);
+ }).then(function(imageBitmap) {
+
+ assert_equals(imageBitmap.width, expectedWidth);
+ assert_equals(imageBitmap.height, expectedHeight);
+
+ const canvas = document.createElement("canvas");
+ canvas.width = 16;
+ canvas.height = 16;
+
+ // debug
+ document.getElementById("results").append(canvas);
+ canvas.setAttribute("style", "width: 100px; height: 100px;");
+
+ const ctx = canvas.getContext("2d");
+ ctx.fillStyle = `rgb(${color}, ${color}, ${color})`;
+ ctx.fillRect(0, 0, 20, 20);
+ ctx.drawImage(imageBitmap, 0, 0);
+
+ for (let [x, y, r, g, b, a] of expectedColors) {
+ _assertPixel(canvas, x,y, r,g,b,a);
+ }
+ });
+ }, name);
+}
+testClip( "simple clip inside",
+ 8, 8, 8, 8, [
+ [ 4, 4, 0,255,0,255], [12, 4, color,color,color,255],
+ [ 4, 12, color,color,color,255], [12, 12, color,color,color,255]
+ ], 8, 8
+);
+testClip( "clip outside negative",
+ -8, -8, 16, 16, [
+ [ 4, 4, color,color,color,255], [12, 4, color,color,color,255],
+ [ 4, 12, color,color,color,255], [12, 12, 0,255,0,255]
+ ], 16, 16
+);
+testClip( "clip outside positive",
+ 8, 8, 16, 16, [
+ [ 4, 4, 0,255,0,255], [12, 4, color,color,color,255],
+ [ 4, 12, color,color,color,255], [12, 12, color,color,color,255]
+ ], 16, 16
+);
+testClip( "clip inside using negative width and height",
+ 24, 24, -16, -16, [
+ [ 4, 4, 0,255,0,255], [12, 4, color,color,color,255],
+ [ 4, 12, color,color,color,255], [12, 12, color,color,color,255]
+ ], 16, 16
+);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html
new file mode 100644
index 0000000000..2ddf3648f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-colorSpaceConversion.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<title>Test colorSpaceConversion option for createImageBitmap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<script src="/common/media.js"></script>
+<script src="common.sub.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body>
+<script>
+function testCanvasDisplayingPattern(canvas, width, height)
+{
+ var tolerance = 10; // high tolerance for differing color management results
+ const check = (x, y, r, g, b, a) =>
+ _assertPixelApprox(canvas, x,y, r,g,b,a, tolerance);
+
+ check(1 * width / 4, 1 * height / 4, 124,0,27,255);
+ check(3 * width / 4, 1 * height / 4, 0,124,46,255);
+ check(1 * width / 4, 3 * height / 4, 60,0,123,255);
+ check(3 * width / 4, 3 * height / 4, 0,0,0,255);
+}
+
+function testDrawImageBitmap(source, options)
+{
+ var canvas = document.createElement("canvas");
+ canvas.width = 20;
+ canvas.height = 20;
+ var ctx = canvas.getContext("2d");
+ return createImageBitmap(source, options).then(imageBitmap => {
+ ctx.drawImage(imageBitmap, 0, 0);
+ testCanvasDisplayingPattern(canvas, 20, 20);
+ });
+}
+
+var wideGamutImageSourceTypes = [
+ {name: 'a bitmap HTMLImageElement', factory: makeMakeHTMLImage("/images/wide-gamut-pattern.png")},
+ {name: 'a Blob', factory: makeBlob("/images/wide-gamut-pattern.png")},
+];
+
+for (let { name, factory } of wideGamutImageSourceTypes) {
+ promise_test(function() {
+ return factory().then(function(img) {
+ return testDrawImageBitmap(img, {colorSpaceConversion: "none"});
+ });
+ }, `createImageBitmap from ${name}, and drawImage on the created ImageBitmap with colorSpaceConversion: none`);
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage-closed.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage-closed.html
new file mode 100644
index 0000000000..3b8644cff5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage-closed.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<title>attempt to draw a closed ImageBitmap to a 2d canvas throws INVALID_STATE_ERR</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<script>
+promise_test(function(t) {
+ return new Promise(function(resolve, reject) {
+ const image = new Image();
+ image.onload = function() { resolve(image); };
+ image.onerror = function() { reject(); };
+ image.src = "/images/green-16x16.png";
+ }).then(function(image) {
+ return createImageBitmap(image, 0, 0, 16, 16);
+ }).then(function(imageBitmap) {
+ imageBitmap.close();
+
+ const canvas = document.createElement("canvas");
+ canvas.width = 16;
+ canvas.height = 16;
+
+ const ctx = canvas.getContext("2d");
+ assert_throws_dom("InvalidStateError", function() { ctx.drawImage(imageBitmap, 0, 0); });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html
new file mode 100644
index 0000000000..5b5698813a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<title>createImageBitmap + drawImage test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<script src="/common/media.js"></script>
+<script src="common.sub.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body>
+<script>
+function testCanvasDisplayingPattern(canvas, width, height, sourceIsVideo)
+{
+ var tolerance = 3;
+ let topLeft = [255, 0, 0, 255];
+ let topRight = [0, 255, 0, 255];
+ let bottomLeft = [0, 0, 255, 255];
+ let bottomRight = [0, 0, 0, 255];
+ if (sourceIsVideo) {
+ // The source video uses colors in the Rec.601 color space whose
+ // values are close to full red, full green, full blue, and black,
+ // but when converted to sRGB, are somewhat different.
+ topLeft = [247, 37, 0, 255];
+ topRight = [63, 251, 0, 255];
+ bottomLeft = [28, 35, 255, 255];
+ bottomRight = [5, 0, 2, 255];
+ }
+ const check = (x, y, [r, g, b, a]) =>
+ _assertPixelApprox(canvas, x,y, r,g,b,a, tolerance);
+ check(1 * width / 4, 1 * height / 4, topLeft);
+ check(3 * width / 4, 1 * height / 4, topRight);
+ check(1 * width / 4, 3 * height / 4, bottomLeft);
+ check(3 * width / 4, 3 * height / 4, bottomRight);
+}
+
+function testDrawImageBitmap(source, args = [], { resizeWidth = 20, resizeHeight = 20 } = {})
+{
+ let sourceIsVideo = source instanceof HTMLVideoElement;
+ var canvas = document.createElement("canvas");
+ canvas.width = resizeWidth;
+ canvas.height = resizeHeight;
+ var ctx = canvas.getContext("2d");
+ return createImageBitmap(source, ...args).then(imageBitmap => {
+ assert_equals(imageBitmap.width, resizeWidth);
+ assert_equals(imageBitmap.height, resizeHeight);
+ ctx.drawImage(imageBitmap, 0, 0);
+ testCanvasDisplayingPattern(canvas, resizeWidth, resizeHeight, sourceIsVideo);
+ });
+}
+
+for (let { name, factory } of imageSourceTypes) {
+ promise_test(function() {
+ return factory().then(function(img) {
+ return testDrawImageBitmap(img);
+ });
+ }, `createImageBitmap from ${name}, and drawImage on the created ImageBitmap`);
+
+ promise_test(function() {
+ return factory().then(function(img) {
+ const options = { resizeWidth: 10, resizeHeight: 10 };
+ return testDrawImageBitmap(img, [options], options);
+ });
+ }, `createImageBitmap from ${name} scaled down, and drawImage on the created ImageBitmap`);
+
+ promise_test(function() {
+ return factory().then(function(img) {
+ const options = { resizeWidth: 40, resizeHeight: 40 };
+ return testDrawImageBitmap(img, [options], options);
+ });
+ }, `createImageBitmap from ${name} scaled up, and drawImage on the created ImageBitmap`);
+
+ promise_test(function() {
+ return factory().then(function(img) {
+ const options = { resizeWidth: 10, resizeHeight: 40 };
+ return testDrawImageBitmap(img, [options], options);
+ });
+ }, `createImageBitmap from ${name} resized, and drawImage on the created ImageBitmap`);
+
+ promise_test(function() {
+ return factory().then(function(img) {
+ return testDrawImageBitmap(img, [20, 20, -20, -20]);
+ });
+ }, `createImageBitmap from ${name} with negative sw/sh, and drawImage on the created ImageBitmap`);
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html
new file mode 100644
index 0000000000..8b2a33e85b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<title>Test that createImageBitmap honors EXIF orientation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>canvas { outline: 1px solid black; margin-right: 1em; }</style>
+<body>
+<script>
+function loadImage(src) {
+ return new Promise(function(resolve) {
+ const image = new Image();
+ image.addEventListener("load", () => resolve(image), { once: true });
+ image.src = src;
+ });
+}
+
+function checkColors(ctx, w, h, expectedColors) {
+ let data = ctx.getImageData(0, 0, w, h).data;
+ for (let [row, col, r, g, b, a] of expectedColors) {
+ let x = col * 80 + 40;
+ let y = row * 80 + 40;
+ let i = (x + y * w) * 4;
+
+ let expected = [r, g, b, a];
+ let actual = [data[i], data[i + 1], data[i + 2], data[i + 3]];
+
+ assert_array_approx_equals(actual, expected, 1, `Pixel value at (${x},${y}) ${expected} =~ ${actual}.`);
+ }
+}
+
+async_test(function(t) {
+ const canvas = document.createElement("canvas");
+ canvas.width = 320;
+ canvas.height = 160;
+ document.body.append(canvas);
+
+ const ctx = canvas.getContext("2d");
+ loadImage("resources/squares_6.jpg")
+ .then((image) => createImageBitmap(image))
+ .then(t.step_func_done(function(imageBitmap) {
+ ctx.drawImage(imageBitmap, 0, 0);
+ checkColors(ctx, canvas.width, canvas.height, [
+ // row, col, r, g, b, a
+ [0, 0, 255, 0, 0, 255],
+ [0, 1, 0, 255, 0, 255],
+ [0, 2, 0, 0, 255, 255],
+ [0, 3, 0, 0, 0, 255],
+ [1, 0, 255, 128, 128, 255],
+ [1, 1, 128, 255, 128, 255],
+ [1, 2, 128, 128, 255, 255],
+ [1, 3, 128, 128, 128, 255],
+ ]);
+ }));
+}, "createImageBitmap with EXIF rotation, imageOrientation from-image, and no cropping");
+
+async_test(function(t) {
+ const canvas = document.createElement("canvas");
+ canvas.width = 320;
+ canvas.height = 160;
+ document.body.append(canvas);
+
+ const ctx = canvas.getContext("2d");
+ loadImage("resources/squares_6.jpg")
+ .then((image) => createImageBitmap(image, { imageOrientation: "flipY" }))
+ .then(t.step_func_done(function(imageBitmap) {
+ ctx.drawImage(imageBitmap, 0, 0);
+ checkColors(ctx, canvas.width, canvas.height, [
+ // row, col, r, g, b, a
+ [0, 0, 255, 128, 128, 255],
+ [0, 1, 128, 255, 128, 255],
+ [0, 2, 128, 128, 255, 255],
+ [0, 3, 128, 128, 128, 255],
+ [1, 0, 255, 0, 0, 255],
+ [1, 1, 0, 255, 0, 255],
+ [1, 2, 0, 0, 255, 255],
+ [1, 3, 0, 0, 0, 255],
+ ]);
+ }));
+}, "createImageBitmap with EXIF rotation, imageOrientation flipY, and no cropping");
+
+async_test(function(t) {
+ const canvas = document.createElement("canvas");
+ canvas.width = 160;
+ canvas.height = 160;
+ document.body.append(canvas);
+
+ const ctx = canvas.getContext("2d");
+ loadImage("resources/squares_6.jpg")
+ .then(image => createImageBitmap(image, 80, 0, 160, 160))
+ .then(t.step_func_done(function(imageBitmap) {
+ ctx.drawImage(imageBitmap, 0, 0);
+ checkColors(ctx, canvas.width, canvas.height, [
+ // row, col, r, g, b, a
+ [0, 0, 0, 255, 0, 255],
+ [0, 1, 0, 0, 255, 255],
+ [1, 0, 128, 255, 128, 255],
+ [1, 1, 128, 128, 255, 255],
+ ]);
+ }));
+}, "createImageBitmap with EXIF rotation, imageOrientation from-image, and cropping");
+
+async_test(function(t) {
+ const canvas = document.createElement("canvas");
+ canvas.width = 160;
+ canvas.height = 160;
+ document.body.append(canvas);
+
+ const ctx = canvas.getContext("2d");
+ loadImage("resources/squares_6.jpg")
+ .then(image => createImageBitmap(image, 80, 0, 160, 160, { imageOrientation: "flipY" }))
+ .then(t.step_func_done(function(imageBitmap) {
+ ctx.drawImage(imageBitmap, 0, 0);
+ checkColors(ctx, canvas.width, canvas.height, [
+ // row, col, r, g, b, a
+ [0, 0, 128, 255, 128, 255],
+ [0, 1, 128, 128, 255, 255],
+ [1, 0, 0, 255, 0, 255],
+ [1, 1, 0, 0, 255, 255],
+ ]);
+ }));
+}, "createImageBitmap with EXIF rotation, imageOrientation flipY, and cropping");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation_none.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation_none.html
new file mode 100644
index 0000000000..807925b88a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-exif-orientation_none.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>Test that createImageBitmap honors EXIF orientation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>canvas { outline: 1px solid black; margin-right: 1em; }</style>
+<body>
+<script>
+function loadImage(src) {
+ return new Promise(function(resolve) {
+ const image = new Image();
+ image.addEventListener("load", () => resolve(image), { once: true });
+ image.src = src;
+ });
+}
+
+function checkColors(ctx, w, h, is_verticle, expectedColors) {
+ let data = ctx.getImageData(0, 0, w, h).data;
+ row_width = 80;
+ col_width = 80;
+
+ for (let [row, col, r, g, b, a] of expectedColors) {
+ let x = col * row_width + 10;
+ let y = row * col_width + 10;
+ let i = (x + y * w) * 4;
+
+ let expected = [r, g, b, a];
+ let actual = [data[i], data[i + 1], data[i + 2], data[i + 3]];
+
+ assert_array_approx_equals(actual, expected, 1, `Pixel value at (${x},${y}) ${expected} =~ ${actual}.`);
+ }
+}
+
+for (let orientation of [1, 2, 3, 4, 5, 6, 7, 8]) {
+ async_test(function(t) {
+ const canvas = document.createElement("canvas");
+ canvas.width = 160;
+ canvas.height = 320;
+ document.body.append(canvas);
+
+ const ctx = canvas.getContext("2d");
+ loadImage(`resources/squares_${orientation}.jpg`)
+ .then((image) => createImageBitmap(image, { imageOrientation: "none" }))
+ .then(t.step_func_done(function(imageBitmap) {
+ ctx.drawImage(imageBitmap, 0, 0, 160, 320);
+
+ checkColors(ctx, canvas.width, canvas.height, false, [
+ // row, col, r, g, b, a
+ [0, 0, 0, 0, 0, 255],
+ [0, 1, 128, 128, 128, 255],
+ [1, 0, 0, 0, 255, 255],
+ [1, 1, 128, 128, 255, 255],
+ [2, 0, 0, 255, 0, 255],
+ [2, 1, 128, 255, 128, 255],
+ [3, 0, 255, 0, 0, 255],
+ [3, 1, 255, 128, 128, 255],
+ ]);
+ }));
+ }, `createImageBitmap with Orientation ${orientation}`);
+}
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html
new file mode 100644
index 0000000000..9b0d2dfb79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-flipY.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<title>createImageBitmap + drawImage test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<script src="/common/media.js"></script>
+<script src="common.sub.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body>
+<script>
+function testCanvasDisplayingPattern(canvas, width, height, sourceIsVideo, flipped)
+{
+ var tolerance = 3;
+ let topLeft = [255, 0, 0, 255];
+ let topRight = [0, 255, 0, 255];
+ let bottomLeft = [0, 0, 255, 255];
+ let bottomRight = [0, 0, 0, 255];
+ if (sourceIsVideo) {
+ // The source video uses colors in the Rec.601 color space whose
+ // values are close to full red, full green, full blue, and black,
+ // but when converted to sRGB, are somewhat different.
+ topLeft = [247, 37, 0, 255];
+ topRight = [63, 251, 0, 255];
+ bottomLeft = [28, 35, 255, 255];
+ bottomRight = [5, 0, 2, 255];
+ }
+ if (flipped) {
+ [topLeft, bottomLeft] = [bottomLeft, topLeft];
+ [topRight, bottomRight] = [bottomRight, topRight];
+ }
+ const check = (x, y, [r, g, b, a]) =>
+ _assertPixelApprox(canvas, x,y, r,g,b,a, tolerance);
+ check(1 * width / 4, 1 * height / 4, topLeft);
+ check(3 * width / 4, 1 * height / 4, topRight);
+ check(1 * width / 4, 3 * height / 4, bottomLeft);
+ check(3 * width / 4, 3 * height / 4, bottomRight);
+}
+
+function testDrawImageBitmap(source, args = [], flipped, { resizeWidth = 20, resizeHeight = 20 } = {})
+{
+ let sourceIsVideo = source instanceof HTMLVideoElement;
+ var canvas = document.createElement("canvas");
+ canvas.width = resizeWidth;
+ canvas.height = resizeHeight;
+ var ctx = canvas.getContext("2d");
+ return createImageBitmap(source, ...args).then(imageBitmap => {
+ assert_equals(imageBitmap.width, resizeWidth);
+ assert_equals(imageBitmap.height, resizeHeight);
+ ctx.drawImage(imageBitmap, 0, 0);
+ testCanvasDisplayingPattern(canvas, resizeWidth, resizeHeight, sourceIsVideo, flipped);
+ });
+}
+
+for (let { name, factory } of imageSourceTypes) {
+ promise_test(function() {
+ return factory().then(function(img) {
+ const options = { imageOrientation: 'from-image' };
+ return testDrawImageBitmap(img, [options], false);
+ });
+ }, `createImageBitmap from ${name} imageOrientation: "from-image", and drawImage on the created ImageBitmap`);
+
+ promise_test(function() {
+ return factory().then(function(img) {
+ const options = { imageOrientation: 'flipY' };
+ return testDrawImageBitmap(img, [options], true);
+ });
+ }, `createImageBitmap from ${name} imageOrientation: "flipY", and drawImage on the created ImageBitmap`);
+
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-in-worker-transfer.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-in-worker-transfer.html
new file mode 100644
index 0000000000..727a8a4978
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-in-worker-transfer.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>createImageBitmap in worker and transfer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+promise_test(function(t) {
+ return new Promise(function(resolve, reject) {
+ var worker = new Worker("createImageBitmap-worker.js");
+ worker.addEventListener("message", function(evt) {
+ var bitmap = evt.data;
+ assert_equals(bitmap.width, 20);
+ assert_equals(bitmap.height, 20);
+ resolve();
+ });
+ worker.postMessage('test');
+ });
+}, 'Transfer ImageBitmap created in worker');
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html
new file mode 100644
index 0000000000..3cae3523ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html
@@ -0,0 +1,239 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<script src="common.sub.js"></script>
+<script>
+
+function makeOversizedCanvas() {
+
+ return new Promise(resolve => {
+ let canvas = document.createElement('canvas');
+ canvas.setAttribute('width', '100000000');
+ canvas.setAttribute('height', '100000000');
+ resolve(canvas);
+ });
+}
+
+function makeOversizedOffscreenCanvas() {
+ return new Promise(resolve =>{
+ let canvas = new OffscreenCanvas(100000000, 100000000);
+ resolve(canvas);
+ });
+}
+
+function makeInvalidBlob() {
+ return new Promise(resolve => {
+ resolve(new Blob()); // Blob with no data cannot be decoded.
+ });
+}
+
+function makeBrokenImage() {
+ return new Promise((resolve, reject) => {
+ const image = new Image();
+ image.src = "data:,x";
+ image.onload = reject;
+ image.onerror = () => resolve(image);
+ });
+}
+
+function makeAvailableButBrokenImage(path) {
+ return new Promise((resolve, reject) => {
+ const image = new Image();
+ image.src = path;
+ image.onload = () => resolve(image);
+ image.onerror = reject;
+ });
+}
+
+testCases = [
+ {
+ description: 'createImageBitmap with <sourceType> source and sw set to 0',
+ promiseTestFunction:
+ (source, t) => {
+ return promise_rejects_js(t, RangeError,
+ createImageBitmap(source, 0, 0, 0, 10));
+ }
+ },
+ {
+ description: 'createImageBitmap with <sourceType> source and sh set to 0',
+ promiseTestFunction:
+ (source, t) => {
+ return promise_rejects_js(t, RangeError,
+ createImageBitmap(source, 0, 0, 10, 0));
+ }
+ },
+ {
+ description: 'createImageBitmap with <sourceType> source and oversized ' +
+ '(unallocatable) crop region',
+ promiseTestFunction:
+ (source, t) => {
+ return createImageBitmap(source, 0, 0, 100000000, 100000000)
+ .then(i => {
+ assert_equals(i.width, 100000000);
+ assert_equals(i.height, 100000000);
+ })
+ .catch(e => {
+ // This case is not explicitly documented in the specification for
+ // createImageBitmap, but it is expected that internal failures
+ // cause InvalidStateError.
+ //
+ // Note: https://bugs.chromium.org/p/chromium/issues/detail?id=799025
+ assert_throws_dom("InvalidStateError", () => { throw e });
+ });
+ }
+ },
+ {
+ description: 'createImageBitmap with <sourceType> source and ' +
+ 'a value of 0 int resizeWidth',
+ promiseTestFunction:
+ (source, t) => {
+ return createImageBitmap(source, {resizeWidth:0, resizeHeight:10})
+ .catch(e => {
+ assert_throws_dom("InvalidStateError", () => { throw e });
+ });
+ }
+ },
+ {
+ description: 'createImageBitmap with <sourceType> source and ' +
+ 'a value of 0 in resizeHeight',
+ promiseTestFunction:
+ (source, t) => {
+ return createImageBitmap(source, {resizeWidth:10, resizeHeight:0})
+ .catch(e => {
+ assert_throws_dom("InvalidStateError", () => { throw e });
+ });
+ }
+ },
+ {
+ description: 'createImageBitmap with <sourceType> source and ' +
+ 'a value between 0 and 1 in resizeWidth',
+ promiseTestFunction:
+ (source, t) => {
+ return createImageBitmap(source, {resizeWidth:0.5, resizeHeight:10})
+ .catch(e => {
+ assert_throws_dom("InvalidStateError", () => { throw e });
+ });
+ }
+ },
+ {
+ description: 'createImageBitmap with <sourceType> source and ' +
+ 'a value between 0 and 1 in resizeHeight',
+ promiseTestFunction:
+ (source, t) => {
+ return createImageBitmap(source, {resizeWidth:10, resizeHeight:0.5})
+ .catch(e => {
+ assert_throws_dom("InvalidStateError", () => { throw e });
+ });
+ }
+ },
+];
+
+// Generate the test matrix for each sourceType + testCase combo.
+imageSourceTypes.forEach(imageSourceType => {
+ testCases.forEach(testCase => {
+ let description = testCase.description.replace('<sourceType>',
+ imageSourceType.name);
+ promise_test( t => {
+ return imageSourceType.factory().then(source => {
+ return testCase.promiseTestFunction(source, t);
+ });
+ }, description);
+ });
+});
+
+promise_test( t => {
+ return promise_rejects_js(t, TypeError, createImageBitmap(undefined));
+}, "createImageBitmap with undefined image source.");
+
+promise_test( t => {
+ return promise_rejects_js(t, TypeError, createImageBitmap(null));
+}, "createImageBitmap with null image source.");
+
+promise_test( t => {
+ var context = document.createElement("canvas").getContext("2d");
+ return promise_rejects_js(t, TypeError, createImageBitmap(context));
+}, "createImageBitmap with CanvasRenderingContext2D image source.");
+
+promise_test( t => {
+ var context = document.createElement("canvas").getContext("webgl");
+ return promise_rejects_js(t, TypeError, createImageBitmap(context));
+}, "createImageBitmap with WebGLRenderingContext image source.");
+
+promise_test( t => {
+ var buffer = new Uint8Array();
+ return promise_rejects_js(t, TypeError, createImageBitmap(buffer));
+}, "createImageBitmap with Uint8Array image source.");
+
+promise_test( t => {
+ var buffer = new ArrayBuffer(8);
+ return promise_rejects_js(t, TypeError, createImageBitmap(buffer));
+}, "createImageBitmap with ArrayBuffer image source.");
+
+promise_test( t => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(new Image()));
+}, "createImageBitmap with empty image source.");
+
+promise_test( t => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(document.createElement('video')));
+}, "createImageBitmap with empty video source.");
+
+promise_test( t => {
+ return makeOversizedCanvas().then(canvas => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(canvas));
+ });
+}, "createImageBitmap with an oversized canvas source.");
+
+promise_test( t => {
+ return makeOversizedOffscreenCanvas().then(offscreenCanvas => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(offscreenCanvas));
+ });
+}, "createImageBitmap with an invalid OffscreenCanvas source.");
+
+promise_test( t => {
+ return makeInvalidBlob().then(blob => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(blob));
+ });
+}, "createImageBitmap with an undecodable blob source.");
+
+promise_test( t => {
+ return makeBrokenImage().then(image => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(image));
+ });
+}, "createImageBitmap with a broken image source.");
+
+promise_test( t => {
+ return makeAvailableButBrokenImage("/images/undecodable.png").then(image => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(image));
+ });
+}, "createImageBitmap with an available but undecodable image source.");
+
+promise_test( t => {
+ return makeAvailableButBrokenImage("/images/red-zeroheight.svg").then(image => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(image));
+ });
+}, "createImageBitmap with an available but zero height image source.");
+
+promise_test( t => {
+ return makeAvailableButBrokenImage("/images/red-zerowidth.svg").then(image => {
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(image));
+ });
+}, "createImageBitmap with an available but zero width image source.");
+
+promise_test( t => {
+ return makeImageBitmap().then(bitmap => {
+ bitmap.close()
+ return promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(bitmap));
+ });
+}, "createImageBitmap with a closed ImageBitmap.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html
new file mode 100644
index 0000000000..ae3d23cfbc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>createImageBitmap: origin-clean flag</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/media.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<div id=log></div>
+<script>
+
+function assert_origin_unclean_getImageData(bitmap) {
+ const context = document.createElement("canvas").getContext("2d");
+ context.drawImage(bitmap, 0, 0);
+ assert_throws_dom("SecurityError", () => {
+ context.getImageData(0, 0, 1, 1);
+ });
+}
+
+function assert_origin_unclean_drawImage(bitmap) {
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ ctx.drawImage(bitmap, 0, 0);
+ assert_throws_dom('SecurityError', () => canvas.toDataURL());
+}
+
+function assert_origin_unclean_transferFromImageBitmap(bitmap) {
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('bitmaprenderer');
+ ctx.transferFromImageBitmap(bitmap);
+ assert_throws_dom('SecurityError', () => canvas.toDataURL());
+}
+
+forEachCanvasSource(get_host_info().HTTP_REMOTE_ORIGIN,
+ get_host_info().HTTP_ORIGIN,
+ (name, factory) => {
+ promise_test(function() {
+ return factory().then(createImageBitmap).then(assert_origin_unclean_getImageData);
+ }, `${name}: origin unclear getImageData`);
+ promise_test(function() {
+ return factory().then(createImageBitmap).then(assert_origin_unclean_drawImage);
+ }, `${name}: origin unclear 2dContext.drawImage`);
+ promise_test(function() {
+ return factory().then(createImageBitmap).then(assert_origin_unclean_transferFromImageBitmap);
+ }, `${name}: origin unclear bitmaprenderer.transferFromImageBitmap`);
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-serializable.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-serializable.html
new file mode 100644
index 0000000000..c185cd9cbd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-serializable.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>createImageBitmap serialize test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/namespaces.js"></script>
+<script src="/common/media.js"></script>
+<script src="common.sub.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<div id=log></div>
+<script>
+let worker, continuations = {};
+setup(function() {
+ worker = new Worker("transfer-worker.js");
+ worker.addEventListener("message", function(event) {
+ let { name, bitmap } = event.data;
+ if (continuations.hasOwnProperty(name)) {
+ continuations[name](bitmap);
+ }
+ });
+});
+
+for (let { name, factory } of imageSourceTypes) {
+ promise_test(function(t) {
+ return factory().then(createImageBitmap).then(function(bitmap) {
+ assert_equals(bitmap.width, 20);
+ assert_equals(bitmap.height, 20);
+
+ worker.postMessage({ name: t.name, bitmap: bitmap });
+
+ assert_equals(bitmap.width, 20);
+ assert_equals(bitmap.height, 20);
+
+ return new Promise(function(resolve) {
+ continuations[t.name] = resolve;
+ });
+ }).then(function(bitmap) {
+ assert_class_string(bitmap, "ImageBitmap");
+ assert_equals(bitmap.width, 20);
+ assert_equals(bitmap.height, 20);
+ });
+ }, `Serialize ImageBitmap created from ${name}`);
+}
+
+promise_test(async (t) => {
+ const url = get_host_info().REMOTE_ORIGIN + '/images/pattern.png';
+ const image = await makeMakeHTMLImage(url)();
+ const bitmap = await createImageBitmap(image);
+
+ assert_throws_dom('DataCloneError', () => worker.postMessage(bitmap));
+}, 'Serializing a non-origin-clean ImageBitmap throws.');
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html
new file mode 100644
index 0000000000..25c1fb6885
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-sizeOverflow.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<title>createImageBitmap with size overflow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+promise_test(function() {
+ var imgData = new ImageData(20, 20);
+ return createImageBitmap(imgData, 4294967400, 10, 10, 10);
+}, "createImageBitmap does not crash or reject the promise when passing very large sx");
+
+promise_test(function() {
+ var imgData = new ImageData(20, 20);
+ return createImageBitmap(imgData, 10, 4294967400, 10, 10);
+}, "createImageBitmap does not crash or reject the promise when passing very large sy");
+
+promise_test(function() {
+ var imgData = new ImageData(20, 20);
+ return createImageBitmap(imgData, 10, 10, 4294967400, 10);
+}, "createImageBitmap does not crash or reject the promise when passing very large sw");
+
+promise_test(function() {
+ var imgData = new ImageData(20, 20);
+ return createImageBitmap(imgData, 10, 10, 10, 4294967400);
+}, "createImageBitmap does not crash or reject the promise when passing very large sh");
+
+promise_test(function() {
+ var imgData = new ImageData(20, 20);
+ return createImageBitmap(imgData, 4294967400, 4294967400, 4294967400, 4294967400);
+}, "createImageBitmap does not crash or reject the promise when passing very large sx, sy, sw and sh");
+
+promise_test(function(t) {
+ var imgData = new ImageData(20, 20);
+ var imageBitmapOptions = {imageOrientation:'from-image', premultiplyAlpha:'default',
+ colorSpaceConversion:'none', resizeHeight:2122252543, resizeQuality:'high'};
+ return createImageBitmap(imgData, 0, 0, 4294967295, 64)
+ .then(imageBitmap => promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(imageBitmap, imageBitmapOptions)));
+}, "createImageBitmap throws an InvalidStateError error with big imageBitmap scaled up in big height");
+
+promise_test(function(t) {
+ var imgData = new ImageData(20, 20);
+ var imageBitmapOptions = {imageOrientation:'from-image', premultiplyAlpha:'default',
+ colorSpaceConversion:'none', resizeWidth:2122252543, resizeQuality:'high'};
+ return createImageBitmap(imgData, 0, 0, 4294967295, 64)
+ .then(imageBitmap => promise_rejects_dom(t, "InvalidStateError",
+ createImageBitmap(imageBitmap, imageBitmapOptions)));
+}, "createImageBitmap throws an InvalidStateError error with big imageBitmap scaled up in big width");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html
new file mode 100644
index 0000000000..3ec02fcbf4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>createImageBitmap transferring test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<script src="common.sub.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<div id=log></div>
+<script>
+let worker, continuations = {};
+setup(function() {
+ worker = new Worker("transfer-worker.js");
+ worker.addEventListener("message", function(event) {
+ let { name, bitmap } = event.data;
+ if (continuations.hasOwnProperty(name)) {
+ continuations[name](bitmap);
+ }
+ });
+});
+
+for (let { name, factory } of imageSourceTypes) {
+ promise_test(function(t) {
+ return factory().then(createImageBitmap).then(function(bitmap) {
+ assert_equals(bitmap.width, 20);
+ assert_equals(bitmap.height, 20);
+
+ worker.postMessage({ name: t.name, bitmap: bitmap }, [bitmap]);
+
+ assert_equals(bitmap.width, 0);
+ assert_equals(bitmap.height, 0);
+
+ return new Promise(function(resolve) {
+ continuations[t.name] = resolve;
+ });
+ }).then(function(bitmap) {
+ assert_class_string(bitmap, "ImageBitmap");
+ assert_equals(bitmap.width, 20);
+ assert_equals(bitmap.height, 20);
+ });
+ }, `Transfer ImageBitmap created from ${name}`);
+}
+
+promise_test(async (t) => {
+ const url = get_host_info().REMOTE_ORIGIN + '/images/pattern.png';
+ const image = await makeMakeHTMLImage(url)();
+ const bitmap = await createImageBitmap(image);
+
+ assert_throws_dom('DataCloneError',
+ () => worker.postMessage(bitmap, [bitmap]));
+}, 'Transferring a non-origin-clean ImageBitmap throws.');
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-worker.js b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-worker.js
new file mode 100644
index 0000000000..67a0904e47
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/createImageBitmap-worker.js
@@ -0,0 +1,17 @@
+function makeBlob() {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/pattern.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+}
+
+addEventListener("message", () => {
+ makeBlob().then(createImageBitmap).then(bitmap => {
+ postMessage(bitmap, [bitmap]);
+ });
+});
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation-expected.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation-expected.html
new file mode 100644
index 0000000000..64b1791afe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation-expected.html
@@ -0,0 +1,18 @@
+<html>
+<body>
+ <canvas id="myCanvas" width="400" height="400"></canvas>
+</body>>
+<script>
+var canvas = document.getElementById('myCanvas');
+ctx = canvas.getContext('2d');
+image = document.createElement("img");
+image.src = "../../../resources/black_white.png"
+image.onload = function() {
+ Promise.all([
+ createImageBitmap(image, { imageOrientation: 'flipY' }),
+ ]).then(function(sprites) {
+ // Draw image onto the canvas
+ ctx.drawImage(sprites[0], 0, 0);
+});
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation.html
new file mode 100644
index 0000000000..e93c17c8e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmap-from-imageData-no-image-rotation.html
@@ -0,0 +1,26 @@
+<html>
+ <link rel="match" href="imageBitmap-from-imageData-no-image-rotation-expected.html" />
+ <style type="text/css">
+ canvas {
+ image-orientation: none;
+ }
+ </style>
+<body>
+ <canvas id="myCanvas" width="400" height="400"></canvas>
+</body>>
+<script>
+var canvas = document.getElementById('myCanvas');
+ctx = canvas.getContext('2d');
+image = document.createElement("img");
+image.src = "../../../resources/black_white.png"
+image.onload = function() {
+ Promise.all([
+ // The image should be flipped and ignoring "image-orientation" setting
+ // in css style.
+ createImageBitmap(image, { imageOrientation: 'flipY' }),
+ ]).then(function(sprites) {
+ // Draw image onto the canvas
+ ctx.drawImage(sprites[0], 0, 0);
+});
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-expected.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-expected.html
new file mode 100644
index 0000000000..bababda44c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<body>
+ <p>Test whether the imageOrientation "from-image" works when creating an ImageBitmap from the ImageData of a canvas, and then transfered to an ImageBitmapRenderingContext.</p>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+
+function drawSquares(ctx) {
+ ctx.fillStyle = 'red';
+ ctx.fillRect(0,0,150,150);
+ ctx.fillStyle = 'green';
+ ctx.fillRect(150,0,300,150);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0,150,150,300);
+}
+
+async function runTest() {
+ const canvas = document.getElementById('canvas');
+ canvas.width = 300;
+ canvas.height = 300;
+ const ctx = canvas.getContext('2d');
+ drawSquares(ctx);
+}
+
+runTest();
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped-expected.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped-expected.html
new file mode 100644
index 0000000000..5e21671973
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped-expected.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<body>
+ <p>Test whether the imageOrientation "flipY" works when creating an ImageBitmap from the ImageData of a canvas, and then transfered to an ImageBitmapRenderingContext.</p>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+
+function drawSquares(ctx) {
+ ctx.fillStyle = 'red';
+ ctx.fillRect(0,150,150,150);
+ ctx.fillStyle = 'green';
+ ctx.fillRect(150,150,300,150);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0,0,150,150);
+}
+
+async function runTest() {
+ const canvas = document.getElementById('canvas');
+ canvas.width = 300;
+ canvas.height = 300;
+ const ctx = canvas.getContext('2d');
+ drawSquares(ctx);
+}
+
+runTest();
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped.html
new file mode 100644
index 0000000000..02e0690876
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<link rel="match" href="imageBitmapRendering-transferFromImageBitmap-flipped-expected.html" />
+<body>
+ <p>Test whether the imageOrientation "flipY" works when creating an ImageBitmap from the ImageData of a canvas, and then transfered to an ImageBitmapRenderingContext.</p>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+
+function drawSquares(ctx) {
+ ctx.fillStyle = 'red';
+ ctx.fillRect(0,0,150,150);
+ ctx.fillStyle = 'green';
+ ctx.fillRect(150,0,300,150);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0,150,150,300);
+}
+
+async function runTest() {
+ const canvas_temp = document.createElement('canvas');
+ canvas_temp.width = 300;
+ canvas_temp.height = 300;
+ const ctx_temp = canvas_temp.getContext('2d');
+ drawSquares(ctx_temp);
+ const imageSource = ctx_temp.getImageData(0, 0, 300, 300);
+ const imageOrientation = 'flipY';
+ imageIDFlipped = await createImageBitmap(imageSource, 0, 0, 300, 300, { imageOrientation });
+ const canvas = document.getElementById('canvas');
+ const ctx = canvas.getContext('bitmaprenderer');
+ ctx.transferFromImageBitmap(imageIDFlipped);
+}
+
+runTest();
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl-expected.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl-expected.html
new file mode 100644
index 0000000000..4f155316f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+
+<body>
+ <p>
+ Test creating an ImageBitmap from the transferToImageBitmap of a webgl OffscreenCanvas, and then
+ transferred to an ImageBitmapRenderingContext.
+ </p>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+
+ function drawSquares(ctx) {
+ ctx.enable(ctx.SCISSOR_TEST);
+ ctx.scissor(0, 150, 150, 150);
+ ctx.clearColor(1, 0, 0, 1);
+ ctx.clear(ctx.COLOR_BUFFER_BIT);
+ ctx.scissor(150, 150, 300, 150);
+ ctx.clearColor(0, 1, 0, 1);
+ ctx.clear(ctx.COLOR_BUFFER_BIT);
+ ctx.scissor(0, 0, 150, 150);
+ ctx.clearColor(0, 0, 1, 1);
+ ctx.clear(ctx.COLOR_BUFFER_BIT);
+ }
+
+ async function runTest() {
+ const canvas = document.getElementById('canvas');
+ canvas.width = 300;
+ canvas.height = 300;
+ const ctx = canvas.getContext('webgl');
+ drawSquares(ctx);
+ }
+
+ runTest();
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl.html
new file mode 100644
index 0000000000..049a3822cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-webgl.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<link rel="match" href="imageBitmapRendering-transferFromImageBitmap-webgl-expected.html" />
+
+<body>
+ <p>
+ Test creating an ImageBitmap from the transferToImageBitmap of a webgl OffscreenCanvas, and then
+ transferred to an ImageBitmapRenderingContext.
+ </p>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+
+ function drawSquares(ctx) {
+ ctx.enable(ctx.SCISSOR_TEST);
+ ctx.scissor(0, 150, 150, 150);
+ ctx.clearColor(1, 0, 0, 1);
+ ctx.clear(ctx.COLOR_BUFFER_BIT);
+ ctx.scissor(150, 150, 300, 150);
+ ctx.clearColor(0, 1, 0, 1);
+ ctx.clear(ctx.COLOR_BUFFER_BIT);
+ ctx.scissor(0, 0, 150, 150);
+ ctx.clearColor(0, 0, 1, 1);
+ ctx.clear(ctx.COLOR_BUFFER_BIT);
+ }
+
+ async function runTest() {
+ const offscreen = new OffscreenCanvas(300, 300);
+ const ctxOffscreen = offscreen.getContext('webgl');
+ drawSquares(ctxOffscreen);
+ const image = offscreen.transferToImageBitmap();
+ const canvas = document.getElementById('canvas');
+ const ctx = canvas.getContext('bitmaprenderer');
+ ctx.transferFromImageBitmap(image);
+ }
+
+ runTest();
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap.html
new file mode 100644
index 0000000000..6d3d886759
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<link rel="match" href="imageBitmapRendering-transferFromImageBitmap-expected.html" />
+<body>
+ <p>Test whether the imageOrientation "from-image" works when creating an ImageBitmap from the ImageData of a canvas, and then transfered to an ImageBitmapRenderingContext.</p>
+ <canvas id="canvas" width="300" height="300"></canvas>
+</body>
+<script>
+
+function drawSquares(ctx) {
+ ctx.fillStyle = 'red';
+ ctx.fillRect(0,0,150,150);
+ ctx.fillStyle = 'green';
+ ctx.fillRect(150,0,300,150);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0,150,150,300);
+}
+
+async function runTest() {
+ const canvas_temp = document.createElement('canvas');
+ canvas_temp.width = 300;
+ canvas_temp.height = 300;
+ const ctx_temp = canvas_temp.getContext('2d');
+ drawSquares(ctx_temp);
+ const imageSource = ctx_temp.getImageData(0, 0, 300, 300);
+ const imageOrientation = 'from-image';
+ imageIDFlipped = await createImageBitmap(imageSource, 0, 0, 300, 300, { imageOrientation });
+ const canvas = document.getElementById('canvas');
+ const ctx = canvas.getContext('bitmaprenderer');
+ ctx.transferFromImageBitmap(imageIDFlipped);
+}
+
+runTest();
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imagebitmap-replication-exif-orientation.html b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imagebitmap-replication-exif-orientation.html
new file mode 100644
index 0000000000..ab4331adef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/imagebitmap-replication-exif-orientation.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Verify that image orientation is propagated when ImageBitmap objects are replicated.</title>
+<link rel="author" title="Justin Novosad" href="mailto:junov@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+
+<body>
+<script>
+// This test is most relevant for browser implementations that apply EXIF image
+// orientation lazily. That is to say that the transform is applied at rasterization
+// time rather than at image decode time. This implies that image orientation metadata
+// is stored internally in the decoded image's data structure. This test ensures
+// that the orientation metadata is correctly carried over when ImageBitmap objects
+// are replicated (serialized/deserialized, copied or transferred).
+
+function checkImageBitmapRotated(bitmap) {
+ assert_equals(bitmap.width, 320, 'Bitmap width');
+ assert_equals(bitmap.height, 160, 'Bitmap height');
+
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+
+ const expected_colors = [
+ // row, col, r, g, b, a
+ [0, 0, 255, 0, 0, 255],
+ [0, 1, 0, 255, 0, 255],
+ [0, 2, 0, 0, 255, 255],
+ [0, 3, 0, 0, 0, 255],
+ [1, 0, 255, 128, 128, 255],
+ [1, 1, 128, 255, 128, 255],
+ [1, 2, 128, 128, 255, 255],
+ [1, 3, 128, 128, 128, 255],
+ ];
+
+ canvas.width = bitmap.width;
+ canvas.height = bitmap.height;
+ ctx.drawImage(bitmap, 0, 0);
+
+ let data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
+ for (let [row, col, r, g, b, a] of expected_colors) {
+ let x = col * 80 + 40;
+ let y = row * 80 + 40;
+ let i = (x + y * canvas.width) * 4;
+ let expected = [r, g, b, a];
+ let actual = [data[i], data[i + 1], data[i + 2], data[i + 3]];
+ assert_array_approx_equals(actual, expected, 1, `Pixel value at (${x},${y}) ${expected} =~ ${actual}.`);
+ }
+}
+
+promise_test(async t => {
+ const response = await fetch("resources/squares_6.jpg");
+ const blob = await response.blob();
+ const image = await createImageBitmap(blob)
+ const image_copy = structuredClone(image);
+ checkImageBitmapRotated(image_copy);
+}, "ImageBitmap from file with EXIF rotation, duplicated via structuredClone");
+
+promise_test(async t => {
+ const image = new Image();
+ image.src = "resources/squares_6.jpg"
+ await new Promise(resolve => image.onload = resolve);
+ const image_copy = await createImageBitmap(image);
+ checkImageBitmapRotated(image_copy);
+}, "ImageBitmap from file with EXIF rotation, loaded via <img>");
+
+promise_test(async t => {
+ const image = new Image();
+ image.src = "resources/squares_6.jpg"
+ // The following has no effect because the image's style is not
+ // processed unless the element is connected to the DOM.
+ image.style.imageOrientation = "none";
+ await new Promise(resolve => image.onload = resolve);
+ const image_copy = await createImageBitmap(image);
+ checkImageBitmapRotated(image_copy);
+}, "ImageBitmap from file with EXIF rotation, loaded via <img> not in DOM, imageOrientation = none");
+
+promise_test(async t => {
+ const image = new Image();
+ document.body.appendChild(image);
+ image.src = "resources/squares_6.jpg"
+ // The style is being processed in this case, but the imageOrientation
+ // CSS property must still have no effect because createImageBitmap
+ // accesses the element's underlying media directly, without being
+ // affected by the image's style (unlike drawImage).
+ image.style.imageOrientation = "none";
+ await new Promise(resolve => image.onload = resolve);
+ const image_copy = await createImageBitmap(image);
+ checkImageBitmapRotated(image_copy);
+}, "ImageBitmap from file with EXIF rotation, loaded via <img> in DOM, imageOrientation = none");
+
+
+promise_test(async t => {
+ const response = await fetch("resources/squares_6.jpg");
+ const blob = await response.blob();
+ const image = await createImageBitmap(blob);
+ const image_copy = await createImageBitmap(image);
+ checkImageBitmapRotated(image_copy);
+}, "ImageBitmap from file with EXIF rotation, duplicated via createImageBitmap");
+
+promise_test(async t => {
+ const worker = new Worker("serialize-worker.js");
+ const response = await fetch("resources/squares_6.jpg");
+ const blob = await response.blob()
+ const image = await createImageBitmap(blob);
+ worker.postMessage({bitmap: image});
+ const bitmap = (await new Promise(resolve => {worker.addEventListener("message", resolve)})).data.bitmap;
+ checkImageBitmapRotated(bitmap);
+}, "ImageBitmap from file with EXIF rotation, duplicated via worker serialization round-trip");
+
+promise_test(async t => {
+ const worker = new Worker("transfer-worker.js");
+ let response = await fetch("resources/squares_6.jpg");
+ let blob = await response.blob();
+ let image = await createImageBitmap(blob);
+ worker.postMessage({bitmap: image}, [image]);
+ const bitmap = (await new Promise(resolve => {worker.addEventListener("message", resolve)})).data.bitmap;
+ checkImageBitmapRotated(bitmap);
+}, "ImageBitmap from file with EXIF rotation, duplicated via worker transfer round-trip");
+
+promise_test(async t => {
+ // This test variant ensures additional code coverage.
+ // By creating a canvas pattern, a reference to the ImageBitmap's
+ // underlying pixel data is held in the source realm. This forces
+ // implementations that do lazy copying to duplicate the pixel
+ // data at transfer time. This test verifies that the lazy
+ // duplication code path (if applicable) carries over the image
+ // orientation metadata.
+ const worker = new Worker("transfer-worker.js");
+ let response = await fetch("resources/squares_6.jpg");
+ let blob = await response.blob();
+ let image = await createImageBitmap(blob);
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ const pattern = ctx.createPattern(image, 'repeat');
+ worker.postMessage({bitmap: image}, [image]);
+ const bitmap = (await new Promise(resolve => {worker.addEventListener("message", resolve)})).data.bitmap;
+ checkImageBitmapRotated(bitmap);
+}, "ImageBitmap from file with EXIF rotation, duplicated via worker transfer round-trip, while referenced by a CanvasPattern");
+
+
+</script>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_1.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_1.jpg
new file mode 100644
index 0000000000..0f0e8866b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_1.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_2.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_2.jpg
new file mode 100644
index 0000000000..526f7a6c82
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_2.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_3.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_3.jpg
new file mode 100644
index 0000000000..a21e521c2d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_3.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_4.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_4.jpg
new file mode 100644
index 0000000000..c4380b1e67
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_4.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_5.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_5.jpg
new file mode 100644
index 0000000000..0bdd89aa1b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_5.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_6.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_6.jpg
new file mode 100644
index 0000000000..f197760a11
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_6.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_7.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_7.jpg
new file mode 100644
index 0000000000..9b1a346888
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_7.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_8.jpg b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_8.jpg
new file mode 100644
index 0000000000..41d2fbe7f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/resources/squares_8.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/serialize-worker.js b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/serialize-worker.js
new file mode 100644
index 0000000000..a76537cc9e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/serialize-worker.js
@@ -0,0 +1,3 @@
+addEventListener('message', evt => {
+ postMessage(evt.data);
+});
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/transfer-worker.js b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/transfer-worker.js
new file mode 100644
index 0000000000..55465a899c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/transfer-worker.js
@@ -0,0 +1,3 @@
+addEventListener('message', evt => {
+ postMessage(evt.data, [evt.data.bitmap]);
+});
diff --git a/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/worker-onmessage-noop.js b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/worker-onmessage-noop.js
new file mode 100644
index 0000000000..c0a352b4d9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/imagebitmap/worker-onmessage-noop.js
@@ -0,0 +1,3 @@
+self.onmessage = function(e) {
+};
+
diff --git a/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers-expected.html b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers-expected.html
new file mode 100644
index 0000000000..873869ea72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Canvas test: unclosed-layers</title>
+<h1>unclosed-layers</h1>
+<p class="desc">Check that unclosed layers aren't rendered.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers.html b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers.html
new file mode 100644
index 0000000000..afb53cfbeb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-layers.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="match" href="unclosed-layers-expected.html">
+<title>Canvas test: unclosed-layers</title>
+<h1>unclosed-layers</h1>
+<p class="desc">Check that unclosed layers aren't rendered.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}});
+ ctx.fillRect(40, 40, 75, 50);
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(50, 50, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers-expected.html b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers-expected.html
new file mode 100644
index 0000000000..8557441f7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Canvas test: unclosed-nested-layers</title>
+<h1>unclosed-nested-layers</h1>
+<p class="desc">Check that unclosed nested layers aren't rendered.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0,0,255,1)';
+ ctx.fillRect(60,60,75,50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers.html b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers.html
new file mode 100644
index 0000000000..ada874a51a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/layers/unclosed-nested-layers.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<link rel="match" href="unclosed-nested-layers-expected.html">
+<title>Canvas test: unclosed-nested-layers</title>
+<h1>unclosed-nested-layers</h1>
+<p class="desc">Check that unclosed nested layers aren't rendered.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ // Missing ctx.endLayer() here.
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001-ref.htm
new file mode 100644
index 0000000000..f85af9aab2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001-ref.htm
@@ -0,0 +1,11 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: "square" lineCap</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ </head>
+ <body>
+ <p>Description: The square value of lineCap means that a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line, must be added at the end of each line.</p>
+ <div><img src='/images/black-rectangle.png' alt='black rect' /></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001.htm b/testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001.htm
new file mode 100644
index 0000000000..583dbc9d13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/line-styles/canvas_linestyles_linecap_001.htm
@@ -0,0 +1,37 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: "square" lineCap</title>
+ <link rel="match" href="canvas_linestyles_linecap_001-ref.htm">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-linecap" />
+ <meta name="assert" content="The square value of lineCap means that a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line, must be added at the end of each line." />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Draw the first red rectangle.
+ ctx.fillStyle ="rgba(255, 0, 0, 1.0)";
+ ctx.fillRect(75, 0, 25, 50);
+
+ // Draw second red rectangle.
+ ctx.fillRect(0, 0, 25, 50);
+
+ // Draw a line with square lineCap.
+ ctx.strokeStyle = "rgba(0, 0, 0, 1.0)";
+ ctx.lineWidth = 50;
+ ctx.lineCap = "square";
+ ctx.beginPath();
+ ctx.moveTo(25, 25);
+ ctx.lineTo(75, 25);
+ ctx.stroke();
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: The square value of lineCap means that a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line, must be added at the end of each line.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_a.html b/testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_a.html
new file mode 100644
index 0000000000..7e692f937d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_a.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<link rel=match href=lineto_ref.html>
+<style>
+ html, body {
+ margin: 0;
+ padding: 0;
+ }
+</style>
+<canvas id="c" width="150" height="150" >
+Your browser does not support the HTML5 canvas tag.</canvas>
+
+<script>
+var c = document.getElementById("c");
+var ctx = c.getContext("2d");
+
+ctx.beginPath();
+ctx.moveTo(20, 20);
+ctx.lineTo(20, 130);
+ctx.lineTo(130, 130);
+ctx.lineTo(130, 20);
+ctx.closePath();
+
+ctx.fillStyle = '#90EE90';
+ctx.fill();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_ref.html b/testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_ref.html
new file mode 100644
index 0000000000..3dc78ff804
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/line-styles/lineto_ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<style>
+ html, body {
+ margin: 0;
+ padding: 0;
+ }
+ div {
+ background: #90EE90;
+ width: 110px;
+ height: 110px;
+ margin: 20px;
+ }
+</style>
+<div></div>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/line-styles/setLineDash.html b/testing/web-platform/tests/html/canvas/element/manual/line-styles/setLineDash.html
new file mode 100644
index 0000000000..6b8d131da4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/line-styles/setLineDash.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>setLineDash</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<canvas id="canvas"></canvas>
+<script>
+test(function() {
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+
+ var initial = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+ ctx.setLineDash(initial);
+ assert_array_equals(ctx.getLineDash(), initial, "line dash sanity");
+
+ ctx.setLineDash([Infinity]);
+ assert_array_equals(ctx.getLineDash(), initial, "Inf doesn't reset line dash");
+
+ ctx.setLineDash([NaN]);
+ assert_array_equals(ctx.getLineDash(), initial, "NaN doesn't reset line dash");
+
+ ctx.setLineDash([-1]);
+ assert_array_equals(ctx.getLineDash(), initial, "Negative doesn't reset line dash");
+}, "Invalid arguments to setLineDash()");
+
+test(function() {
+ var canvas = document.getElementById('canvas');
+ var ctx = canvas.getContext('2d');
+ assert_equals(ctx.lineDashOffset, 0);
+
+ ctx.setLineDash([15, 10]);
+ ctx.lineDashOffset = 5;
+ ctx.strokeRect(10,10,100,100);
+
+ var lineDash = ctx.getLineDash();
+ assert_array_equals(lineDash, [15, 10]);
+ assert_equals(ctx.lineDashOffset, 5);
+
+ ctx.setLineDash([5, 10, 15]);
+ ctx.strokeRect(20, 20, 120, 120);
+ lineDash = ctx.getLineDash();
+ assert_array_equals(lineDash, [5, 10, 15, 5, 10, 15]);
+
+ ctx.setLineDash(["1", 2]);
+ lineDash = ctx.getLineDash();
+ assert_array_equals(lineDash, [1, 2]);
+
+ ctx.clearRect(0, 0, 700, 700);
+ assert_equals(ctx.lineDashOffset, 5);
+
+ ctx.setLineDash([20, 10]);
+ ctx.lineDashOffset = 0;
+ // Make the test immune to plaform anti-aliasing discrepancies.
+ ctx.lineWidth = 4;
+ ctx.strokeStyle = '#00FF00';
+ ctx.strokeRect(10.5, 10.5, 30, 30);
+
+ _assertPixel(canvas, 25, 10, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 35, 10, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 40, 25, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 40, 35, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 25, 40, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 15, 40, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 10, 25, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 10, 15, 0, 0, 0, 0, 0);
+
+ // Verify that lineDashOffset works as expected.
+ ctx.lineDashOffset = 20;
+ ctx.strokeRect(50.5, 10.5, 30, 30);
+ _assertPixel(canvas, 55, 10, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 65, 10, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 80, 15, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 80, 25, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 75, 40, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 65, 40, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 50, 35, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 50, 25, 0, 255, 0, 255, 0);
+
+ // Verify negative lineDashOffset.
+ ctx.lineDashOffset = -10;
+ ctx.strokeRect(90.5, 10.5, 30, 30);
+ _assertPixel(canvas, 95, 10, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 105, 10, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 120, 15, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 120, 25, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 115, 40, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 105, 40, 0, 255, 0, 255, 0);
+ _assertPixel(canvas, 90, 35, 0, 0, 0, 0, 0);
+ _assertPixel(canvas, 90, 25, 0, 255, 0, 255, 0);
+
+ // Ensure that all zeros or negative pattern does not cause error state in
+ // context.
+ ctx.setLineDash([0, 0]);
+ ctx.strokeRect(130.5, 10.5, 10, 10);
+ ctx.setLineDash([-1]);
+ ctx.strokeRect(130.5, 10.5, 10, 10);
+ _assertPixel(canvas, 135, 15, 0, 0, 0, 0, 0);
+ ctx.fillStyle = '#00FF00';
+ ctx.fillRect(130, 10, 10, 10);
+ _assertPixel(canvas, 135, 15, 0, 255, 0, 255, 0);
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_001.htm b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_001.htm
new file mode 100644
index 0000000000..1763950d61
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_001.htm
@@ -0,0 +1,60 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: Shadows for linear gradients</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#shadows" />
+ <meta name="assert" content="Shadows must be drawn for linear gradients." />
+ <script type="text/javascript">
+ async_test(function(t) {
+ window.addEventListener("load", t.step_func_done(function runTest() {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Draw a red rectangle.
+ ctx.fillStyle = "rgba(255, 0, 0, 1.0)";
+ ctx.fillRect(150, 0, 100, 50);
+
+ // Set shadow styles to draw a black shadow to overlap the red rectangle.
+ ctx.shadowOffsetX = 150;
+ ctx.shadowColor = "rgba(0, 0, 0, 1.0)";
+
+ // Draw a left to right, green-to-blue linear gradient.
+ var lingrad = ctx.createLinearGradient(0, 50, 100, 50);
+ lingrad.addColorStop(0, "rgba(0, 255, 0, 1.0)");
+ lingrad.addColorStop(1, "rgba(0, 0, 255, 1.0)");
+ ctx.fillStyle = lingrad;
+ ctx.fillRect(0, 0, 100, 50);
+
+ // Check the red is gone
+ var data = ctx.getImageData(150, 0, 100, 50);
+ for (var i = 0; i < data.data.length; i += 4) {
+ var r = data.data[i];
+ var g = data.data[i+1];
+ var b = data.data[i+2];
+ var a = data.data[i+3];
+ assert_equals(r, 0, "r channel");
+ assert_equals(g, 0, "g channel");
+ assert_equals(b, 0, "b channel");
+ assert_equals(a, 0xFF, "a channel");
+ }
+
+ for (var j = 0; j < data.data.length; j += 4) {
+ var r2 = data.data[j];
+ var g2 = data.data[j+1];
+ var b2 = data.data[j+2];
+ var a2 = data.data[j+3];
+ assert_false(r2 == 0xFF && g2 == 0 && b2 == 0 && a2 == 0xFF, "no red");
+ }
+ }));
+ }, "linear gradient fillRect draws shadow (black rectange)");
+ </script>
+ </head>
+ <body>
+ <p>Description: Shadows must be drawn for linear gradients.</p>
+ <p>Test passes if there is one gradient filled rectangle and one black rectangle, and no red seen on the page.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002-ref.htm
new file mode 100644
index 0000000000..0658be808e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002-ref.htm
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: Shadows for images</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#shadows" />
+ <meta name="assert" content="Shadows must be drawn for images." />
+ <script type="text/javascript">
+ function runTest() {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Draw a black rectangle image on the canvas.
+ var img = document.getElementById("imgBlackRect");
+ ctx.drawImage(img, 0, 0);
+ ctx.drawImage(img, 150, 0);
+ }
+ </script>
+
+ </head>
+ <body onload="runTest()">
+ <p>Description: Shadows must be drawn for images.</p>
+ <p>Test passes if two black rectangles are shown and there is no red visible on the page.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ <img id="imgBlackRect" style="display:none;" width="100" height="50" src="/images/black-rectangle.png">
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002.htm b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002.htm
new file mode 100644
index 0000000000..908fffea13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_002.htm
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: Shadows for images</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#shadows" />
+ <link rel="match" href="canvas_shadows_002-ref.htm" />
+ <meta name="assert" content="Shadows must be drawn for images." />
+ <script type="text/javascript">
+ function runTest() {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Draw a red rectangle.
+ ctx.fillStyle = "rgba(255, 0, 0, 1.0)";
+ ctx.fillRect(150, 0, 100, 50);
+
+ // Set shadow styles to draw a black shadow to overlap the red rectangle.
+ ctx.shadowOffsetX = 150;
+ ctx.shadowColor = "rgba(0, 0, 0, 1.0)";
+
+ // Draw a black rectangle image on the canvas.
+ var img = document.getElementById("imgBlackRect");
+ ctx.drawImage(img, 0, 0);
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: Shadows must be drawn for images.</p>
+ <p>Test passes if two black rectangles are shown and there is no red visible on the page.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ <img id="imgBlackRect" style="display:none" width="100" height="50" src="/images/black-rectangle.png">
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors-expected.html b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors-expected.html
new file mode 100644
index 0000000000..e568aa9a5c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors-expected.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>System Colors work for Canvas Drop-Shadow Filters</title>
+</head>
+<body>
+<div style="width: 100px; height: 100px; background-color: black"></div>
+<div style="width: 100px; height: 100px; background-color: GrayText"></div>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors.html b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors.html
new file mode 100644
index 0000000000..42978fb18f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/shadows/canvas_shadows_system_colors.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>System Colors work for Canvas Drop-Shadow Filters</title>
+ <link rel="match" href="canvas_shadows_system_colors-expected.html">
+</head>
+<body>
+<canvas id='c' width="100" height="200">
+<script>
+// See crbug.com/1226282 and crbug.com/1081945
+// A reference test is necessary because system colors do not have defined
+// numeric values. Here we're comparing 'GrayText' to css 'GrayText'.
+var ctx = document.getElementById('c').getContext('2d');
+ctx.filter = 'drop-shadow(0px 100px 0 GrayText)';
+ctx.fillRect(0,0,100,100);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/shadows/shadowBlur_gaussian_tolerance.1.html b/testing/web-platform/tests/html/canvas/element/manual/shadows/shadowBlur_gaussian_tolerance.1.html
new file mode 100644
index 0000000000..eec27bf108
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/shadows/shadowBlur_gaussian_tolerance.1.html
@@ -0,0 +1,191 @@
+<!DOCTYPE HTML>
+<title>Test of canvas shadowBlur Gaussian blur pixel values</title>
+<meta charset=UTF-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<h1>Test of canvas shadowBlur Gaussian blur pixel values</h1>
+<script>
+
+/**
+ * See https://en.wikipedia.org/wiki/Error_function#Approximation_with_elementary_functions
+ */
+function erf(x) {
+ if (x < 0) {
+ return -erf(-x);
+ }
+ var p = 0.3275911, a1 = 0.254829592, a2 = -0.284496736, a3 = 1.421413741, a4 = -1.453152027, a5 = 1.061405429;
+ var t = 1 / (1 + p * x);
+ return 1 - Math.exp(-x * x) * t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5))));
+}
+
+/**
+ * See https://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function
+ * and https://en.wikipedia.org/wiki/Normal_distribution#Numerical_approximations_for_the_normal_CDF
+ */
+function standard_normal_distribution_cumulative(x) {
+ return 0.5 * (1 + erf(x / Math.SQRT2));
+}
+
+/**
+ * Verify a single pixel; helper for run_blur_test.
+ * params - same as run_blur_test
+ * row & col - relative to the corner of the rectangle being blurred
+ * actual - actual color found there on the canvas
+ */
+function test_pixel(params, row, col, shadowOffset, actual) {
+ var expected_gaussian;
+ if (params.expected_sigma > 0) {
+ // Compute positions within a standard normal distribution (i.e.,
+ // where mean (μ) is and standard deviation (σ) is 1) in both
+ // dimensions.
+ // Add 0.5 because we want the middle of the pixel rather than the edge.
+ var pos_x = (col - shadowOffset + 0.5) / params.expected_sigma;
+ var pos_y = (row - shadowOffset + 0.5) / params.expected_sigma;
+
+ // Find the expected color value based on a Gaussian blur function.
+ // Since we're blurring the corner of a "very large" rectangle, we
+ // can, instead of sampling all of the pixels, use the cumulative
+ // form of the normal (Gaussian) distribution and pass it the
+ // position of the color transition (the edges of the rectangle),
+ // since we know everything above and to the left of that position
+ // is one color, and everything that is either below or to the right
+ // of that position is another color.
+ //
+ // NOTE: This assumes color-interpolation happens in sRGB rather
+ // than linearRGB. The canvas spec doesn't appear to be clear on
+ // this point. If it were linearRGB, we'd need to apply the
+ // correction after doing this calculation. (No correction to the
+ // input is needed since the input is all 0 or 1.)
+ expected_gaussian = standard_normal_distribution_cumulative(-pos_x) *
+ standard_normal_distribution_cumulative(-pos_y);
+ } else {
+ if (col >= shadowOffset || row >= shadowOffset) {
+ expected_gaussian = 0;
+ } else {
+ expected_gaussian = 1;
+ }
+ }
+ // TODO: maybe also compute expected value by triple box blur?
+
+ /*
+ * https://html.spec.whatwg.org/multipage/canvas.html#when-shadows-are-drawn
+ * describes how to draw shadows in canvas. It says, among other things:
+ *
+ * Perform a 2D Gaussian Blur on B, using σ as the standard deviation.
+ *
+ * without giving *any* allowance for error.
+ *
+ * However, other specifications that require Gaussian blurs allow some
+ * error; https://www.w3.org/TR/css-backgrounds-3/#shadow-blur allows up to
+ * 5%, and https://drafts.fxtf.org/filter-effects/#feGaussianBlurElement
+ * allows use of a triple box blur which is within 3%.
+ *
+ * Since expecting zero error is unreasonable, this test tests for the least
+ * restrictive of these bounds, the 5% error.
+ *
+ * Note that this allows 5% error in the color component, but there's no
+ * tolerance for error in the position; see comment below about sizes.
+ */
+
+ // Allow any rounding direction.
+ var min_b = Math.max( 0, Math.floor((expected_gaussian - 0.05) * 255));
+ var max_b = Math.min(255, Math.ceil ((expected_gaussian + 0.05) * 255));
+ var min_r = 255 - max_b;
+ var max_r = 255 - min_b;
+
+ var pos = "at row " + row + " col " + col + " ";
+
+ assert_true(min_r <= actual.r && actual.r <= max_r,
+ pos + "red component " + actual.r + " should be between " +
+ min_r + " and " + max_r + " (inclusive).");
+ assert_true(min_b <= actual.b && actual.b <= max_b,
+ pos + "blue component " + actual.b + " should be between " +
+ min_b + " and " + max_b + " (inclusive).");
+ assert_equals(actual.g, 0, pos + "green component should be 0");
+ assert_equals(actual.a, 255, pos + "alpha component should be 255");
+}
+
+/**
+ * Run a test of a single shadowBlur drawing operation. Expects a
+ * parameters object containing:
+ * name - name of test
+ * canvas_width - width of canvas to create
+ * canvas_height - height of canvas to create
+ * shadowBlur - shadowBlur to use for the test drawing operation
+ * expected_sigma - the standard deviation of the gaussian function
+ * that shadowBlur is expected to produce
+ * pixel_skip - how many pixels to skip when sampling results. Should
+ * be relatively prime with canvas_width.
+ */
+function run_blur_test(params) {
+ test(function() {
+ var canvas = document.createElement("canvas");
+ canvas.setAttribute("width", params.canvas_width);
+ canvas.setAttribute("height", params.canvas_height);
+ document.body.appendChild(canvas);
+ var cx = canvas.getContext("2d");
+
+ cx.fillStyle = "red";
+ cx.fillRect(0, 0, params.canvas_width, params.canvas_height);
+
+ // Fill a huge rect just to the top and left of the canvas, with its shadow
+ // blur centered at the middle of the canvas.
+ let edge = Math.floor(params.canvas_width / 2); // position of vertical
+ let big = Math.max(Math.ceil(params.expected_sigma * 1000),
+ params.canvas_width,
+ params.canvas_height);
+ cx.shadowBlur = params.shadowBlur;
+ cx.fillStyle = "green";
+ cx.shadowColor = "blue";
+ cx.shadowOffsetX = edge;
+ cx.shadowOffsetY = edge;
+ cx.fillRect(-big, -big, big, big);
+
+ var imageData =
+ cx.getImageData(0, 0, params.canvas_width, params.canvas_height);
+ for (var i = 0, i_max = params.canvas_width * params.canvas_height;
+ i < i_max;
+ i += params.pixel_skip) {
+ var row = Math.floor(i / params.canvas_width);
+ var col = i - row * params.canvas_width;
+
+ var actual = { r: imageData.data[i * 4],
+ g: imageData.data[i * 4 + 1],
+ b: imageData.data[i * 4 + 2],
+ a: imageData.data[i * 4 + 3] };
+
+ test_pixel(params, row, col, edge, actual);
+ }
+ }, "shadowBlur Gaussian pixel values for " + params.name);
+}
+
+run_blur_test({
+ name: "no blur",
+ canvas_width: 4,
+ canvas_height: 4,
+ shadowBlur: 0,
+ expected_sigma: 0,
+ pixel_skip: 1
+});
+run_blur_test({
+ name: "small blur",
+ canvas_width: 20,
+ canvas_height: 20,
+ // Try to test something smaller than 8 due to historic change in
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=10647 , but not too
+ // small, to avoid the error from rounding to individual pixels worth
+ // of box blur.
+ shadowBlur: 6,
+ expected_sigma: 3,
+ pixel_skip: 3
+});
+run_blur_test({
+ name: "large blur",
+ canvas_width: 100,
+ canvas_height: 100,
+ shadowBlur: 30,
+ expected_sigma: 15,
+ pixel_skip: 13
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected-ref.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected-ref.html
new file mode 100644
index 0000000000..b36d29b97f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>HTML Canvas reference</title>
+<body>
+<canvas id=c>
+</body>
+<script>
+var c = document.getElementById("c");
+var ctx = c.getContext("2d");
+ctx.font = "50px monospace";
+ctx.fillText("Hello", 50, 75);
+ctx.font = "25px serif";
+ctx.fillText("World", 100, 100);
+c.style.border = "3px solid cyan";
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected.html
new file mode 100644
index 0000000000..a1715f6663
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.disconnected.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>HTML Canvas testcase: canvas element not in document</title>
+<link rel=match href="canvas.2d.disconnected-ref.html">
+<meta name=fuzzy content="maxDifference=0-23;totalPixels=0-829">
+<body>
+</body>
+<script>
+var d = new Document();
+var c = d.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+var ctx = c.getContext("2d");
+ctx.font = "50px monospace";
+ctx.fillText("Hello", 50, 75);
+ctx.font = "25px serif";
+ctx.fillText("World", 100, 100);
+c.toBlob((blob) => {
+ var img = document.createElement("img");
+ const url = URL.createObjectURL(blob);
+ img.src = url;
+ img.style.border = "3px solid cyan";
+ document.body.appendChild(img);
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch-ref.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch-ref.html
new file mode 100644
index 0000000000..00ecdccad3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+function draw() {
+ ctx.font = '25px test';
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+document.fonts.add(f);
+
+f.load().then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.condensed.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.condensed.html
new file mode 100644
index 0000000000..72db41f007
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.condensed.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "condensed";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.expanded.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.expanded.html
new file mode 100644
index 0000000000..8a13ba13fc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.expanded.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "expanded";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-condensed.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-condensed.html
new file mode 100644
index 0000000000..afa910f62c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-condensed.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = extra-condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "extra-condensed";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "extra-condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-expanded.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-expanded.html
new file mode 100644
index 0000000000..d10d4d9312
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.extra-expanded.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = extra-expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "extra-expanded";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "extra-expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.normal.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.normal.html
new file mode 100644
index 0000000000..e8fd66acad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.normal.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = normal and shows as fail for
+// fontStretch = expanded or condensed.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/fail.woff)');
+f.stretch = "expanded";
+document.fonts.add(f);
+
+var f1 = new FontFace('test', 'url(/fonts/pass.woff)');
+document.fonts.add(f1);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+f2.stretch = "condensed";
+document.fonts.add(f2);
+
+Promise.all([f.load(), f1.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-condensed.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-condensed.html
new file mode 100644
index 0000000000..2ac9719595
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-condensed.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = semi-condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "semi-condensed";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "semi-condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-expanded.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-expanded.html
new file mode 100644
index 0000000000..3c9fa27894
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.semi-expanded.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = semi-expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "semi-expanded";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "semi-expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-condensed.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-condensed.html
new file mode 100644
index 0000000000..2b0426e976
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-condensed.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = ultra-condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "ultra-condensed";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "ultra-condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-expanded.html b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-expanded.html
new file mode 100644
index 0000000000..5b4979de86
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas.2d.fontStretch.ultra-expanded.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = ultra-expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "ultra-expanded";
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "ultra-expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001-ref.htm
new file mode 100644
index 0000000000..1a19757e00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001-ref.htm
@@ -0,0 +1,22 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: Ignore property-independent style sheet syntax "inherit" in Text (reference)</title>
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ ctx.font = "40px Ahem";
+ ctx.fillText("Filler", 5, 50);
+ ctx.fillText("Filler", 5, 100);
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: Ignore "inherit" property-independent style sheet syntax without assigning a new font value.</p>
+ <p>Test passes if there are two identical black boxes below.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001.htm b/testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001.htm
new file mode 100644
index 0000000000..923ce71c07
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/text/canvas_text_font_001.htm
@@ -0,0 +1,33 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: Ignore property-independent style sheet syntax "inherit" in Text</title>
+ <link rel="match" href="canvas_text_font_001-ref.htm" />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-font" />
+ <meta name="assert" content=": Ignore 'inherit' property-independent style sheet syntax without assigning a new font value." />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Assign a valid font.
+ ctx.font = "40px Ahem";
+
+ // Assign property-independent style sheet syntax 'inherit' as font (this must be ignored).
+ ctx.font = "20px inherit";
+ ctx.fillText("Filler", 5, 50);
+
+ // Assign a valid font which was used earlier.
+ ctx.font = "40px Ahem";
+ ctx.fillText("Filler", 5, 100);
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: Ignore "inherit" property-independent style sheet syntax without assigning a new font value.</p>
+ <p>Test passes if there are two identical black boxes below.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.state.saverestore.imageSmoothingEnabled.html b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.state.saverestore.imageSmoothingEnabled.html
new file mode 100644
index 0000000000..e99be83d5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.state.saverestore.imageSmoothingEnabled.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CanvasRenderingContext2D imageSmoothingEnabled save/restore test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing">
+<script>
+function createTestImage() {
+ var image = document.createElement('canvas');
+ var imgctx = image.getContext('2d');
+ imgctx.fillStyle = "#F00";
+ imgctx.fillRect(0, 0, 2, 2);
+ imgctx.fillStyle = "#0F0";
+ imgctx.fillRect(0, 0, 1, 1);
+ return image;
+}
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ ctx.save();
+ ctx.imageSmoothingEnabled = false;
+ ctx.restore();
+ assert_equals(ctx.imageSmoothingEnabled, true);
+}, "Test that restore() undoes any modifications to imageSmoothingEnabled.");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ ctx.imageSmoothingEnabled = false;
+ var old = ctx.imageSmoothingEnabled;
+ ctx.save();
+ assert_equals(ctx.imageSmoothingEnabled, old);
+ ctx.restore();
+}, "Test that save() doesn't modify the values of imageSmoothingEnabled.");
+
+test(function() {
+ var ctx = document.createElement('canvas').getContext('2d');
+ ctx.imageSmoothingEnabled = false;
+ ctx.save();
+ ctx.imageSmoothingEnabled = true;
+ ctx.restore();
+ var image = createTestImage();
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(0, 0, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that restoring actually changes smoothing and not just the attribute value.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.zero.size.canvas.html b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.zero.size.canvas.html
new file mode 100644
index 0000000000..273e5c7484
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/2d.zero.size.canvas.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+</head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<canvas id="canvas" width="0" height="0"></canvas>
+<body>
+<script>
+test(function() {
+ var context = document.getElementById("canvas").getContext("2d");
+ context.fillStyle = "green";
+}, 'This test ensures that accessing the context of a zero sized canvas does not crash.');
+</script>
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001-ref.htm
new file mode 100644
index 0000000000..aee610d2ec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001-ref.htm
@@ -0,0 +1,11 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: restore() pops top entry in drawing state stack</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ </head>
+ <body>
+ <p>Description: restore() pops the top entry in the drawing state stack.</p>
+ <div><img src='/images/threecolors.png' alt='3 colors'></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001.htm b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001.htm
new file mode 100644
index 0000000000..6d5a3cb20f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/the-canvas-state/canvas_state_restore_001.htm
@@ -0,0 +1,42 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: restore() pops top entry in drawing state stack</title>
+ <link rel="match" href="canvas_state_restore_001-ref.htm">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#the-canvas-state" />
+ <meta name="assert" content="restore() pops the top entry in the drawing state stack." />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+ ctx.fillStyle = "rgba(255, 0, 0, 1.0)";
+ ctx.fillRect(0, 0, 99, 50);
+
+ // Save colors to the stack as separate drawing states.
+ ctx.fillStyle = "rgba(255, 255, 0, 1.0)";
+ ctx.save();
+ ctx.fillStyle = "rgba(0, 0, 255, 1.0)";
+ ctx.save();
+ ctx.fillStyle = "rgba(0, 255, 0, 1.0)";
+ ctx.save();
+
+ // Modify the current fillStyle.
+ ctx.fillStyle = "rgba(255, 0, 0, 1.0)";
+
+ // Restore the drawing states previously saved and draw with them.
+ ctx.restore();
+ ctx.fillRect(66, 0, 33, 50);
+ ctx.restore();
+ ctx.fillRect(33, 0, 33, 50);
+ ctx.restore();
+ ctx.fillRect(0, 0, 33, 50);
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: restore() pops the top entry in the drawing state stack.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/transformations/2d.transformation.getTransform.html b/testing/web-platform/tests/html/canvas/element/manual/transformations/2d.transformation.getTransform.html
new file mode 100644
index 0000000000..664efd50e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/transformations/2d.transformation.getTransform.html
@@ -0,0 +1,39 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+// Ensure that context2d.getTransform works
+const epsilon = 1e-5;
+const canvas = document.createElement('canvas');
+const ctx = canvas.getContext('2d');
+
+test(function(t) {
+ assert_array_equals(ctx.getTransform().toFloat32Array(),
+ [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ "Assert that an untransformed matrix is identity");
+
+ ctx.scale(2, 3);
+ transform = ctx.getTransform();
+ assert_array_equals(ctx.getTransform().toFloat32Array(),
+ [2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ "Assert that context2d scaling works");
+
+ ctx.rotate(Math.PI/2);
+ transform = ctx.getTransform();
+ assert_array_approx_equals(ctx.getTransform().toFloat32Array(),
+ [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], epsilon,
+ "Assert that context2d rotate works");
+
+ ctx.translate(1, -1);
+ transform = ctx.getTransform();
+ assert_array_approx_equals(ctx.getTransform().toFloat32Array(),
+ [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 1], epsilon,
+ "Assert context2d translate works.");
+
+ ctx.resetTransform();
+ assert_array_equals(ctx.getTransform().toFloat32Array(),
+ [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ "Assert that a reset matrix is identity");
+}, 'This test ensures that getTransform works correctly.');
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001-ref.html b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001-ref.html
new file mode 100644
index 0000000000..caeea04cef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<style>
+ html, body, div {
+ margin: 0;
+ padding: 0;
+ }
+ div {
+ width: 75px;
+ height: 75px;
+ float: left;
+ }
+</style>
+
+<div style="background-color:red"></div>
+<div style="clear:left"></div>
+<div style="background-color:blue"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001.html b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001.html
new file mode 100644
index 0000000000..c12acbf6f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_reset_001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="match" href="canvas_transformations_reset_001-ref.html">
+<style>
+ html, body {
+ margin: 0;
+ padding: 0;
+ }
+</style>
+<canvas id="c" width="150" height="150"></canvas>
+<script>
+var c = document.getElementById("c");
+var ctx = c.getContext("2d");
+
+ctx.translate(75, 75);
+ctx.fillStyle = 'blue';
+ctx.fillRect(0, 0, 75, 75);
+
+ctx.resetTransform();
+ctx.fillStyle = 'red';
+ctx.fillRect(0, 0, 75, 75);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001-ref.htm b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001-ref.htm
new file mode 100644
index 0000000000..1201bcca9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001-ref.htm
@@ -0,0 +1,11 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>HTML5 Canvas Test: scale() transformation</title>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ </head>
+ <body>
+ <p>Description: The scale(x, y) method must add the scaling transformation described by the arguments to the transformation matrix.</p>
+ <div><img alt='black rectangle' src="/images/black-rectangle.png"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001.htm b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001.htm
new file mode 100644
index 0000000000..73f71351ea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/transformations/canvas_transformations_scale_001.htm
@@ -0,0 +1,31 @@
+<!doctype HTML>
+
+<html>
+ <head>
+ <title>HTML5 Canvas Test: scale() transformation</title>
+ <link rel="match" href="canvas_transformations_scale_001-ref.htm">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="http://www.w3.org/TR/2dcontext/#dom-context-2d-scale" />
+ <meta name="assert" content="The scale(x, y) method must add the scaling transformation described by the arguments to the transformation matrix." />
+ <script type="text/javascript">
+ function runTest()
+ {
+ var canvas = document.getElementById("canvas1");
+ var ctx = canvas.getContext("2d");
+
+ // Draw a red rectangle.
+ ctx.fillStyle = "rgba(255, 0, 0, 1.0)";
+ ctx.fillRect(0, 0, 100, 50);
+
+ // Draw a black rectangle with scaling.
+ ctx.fillStyle = "rgba(0, 0, 0, 1.0)";
+ ctx.scale(2, 2);
+ ctx.fillRect(0, 0, 50, 25);
+ }
+ </script>
+ </head>
+ <body onload="runTest()">
+ <p>Description: The scale(x, y) method must add the scaling transformation described by the arguments to the transformation matrix.</p>
+ <canvas id="canvas1" width="300" height="150">Browser does not support HTML5 Canvas.</canvas>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/transformations/transform_a.html b/testing/web-platform/tests/html/canvas/element/manual/transformations/transform_a.html
new file mode 100644
index 0000000000..8c1f59efda
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/transformations/transform_a.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset=utf-8>
+<link rel=match href=transform_ref.html>
+<style>
+html, body {
+ margin: 0;
+}
+</style>
+<canvas id=c width=400 height=300></canvas>
+<script>
+var canvas = document.getElementById('c');
+var ctx = canvas.getContext('2d');
+ctx.scale(3, 3);
+ctx.fillStyle = 'rgb(255, 0, 0)';
+ctx.beginPath();
+ctx.moveTo(10, 10);
+ctx.bezierCurveTo(10, 10, 20, 10, 20, 10);
+ctx.bezierCurveTo(20, 10, 20, 20, 20, 20);
+ctx.bezierCurveTo(20, 20, 10, 20, 10, 20);
+ctx.closePath();
+ctx.fill();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/transformations/transform_ref.html b/testing/web-platform/tests/html/canvas/element/manual/transformations/transform_ref.html
new file mode 100644
index 0000000000..2a166c36ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/transformations/transform_ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<style>
+html, body {
+ margin: 0;
+}
+section {
+ position: absolute;
+ background: rgb(255, 0, 0);
+ width: 30px;
+ height: 30px;
+ top: 30px;
+ left: 30px;
+}
+</style>
+<section></section>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1-expected.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1-expected.htm
new file mode 100644
index 0000000000..3272f32fb8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1-expected.htm
@@ -0,0 +1,10 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ </head>
+ <body>
+ <p>There should be no text below this, because the text is inside a canvas element.
+ The canvas is never closed, and the rest of the body ends up inside it.</p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1.htm
new file mode 100644
index 0000000000..5e0c914755
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-1.htm
@@ -0,0 +1,14 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ <link rel="match" href="unclosed-canvas-1-expected.htm">
+ <meta name="assert" content="Test what if canvas tag is unclosed in tag p" />
+ <script type="text/javascript"></script>
+ </head>
+ <body>
+ <p>There should be no text below this, because the text is inside a canvas element.
+ The canvas is never closed, and the rest of the body ends up inside it. </p>
+ <canvas>This text should NOT be visible if JavaScript is enabled.
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2-expected.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2-expected.htm
new file mode 100644
index 0000000000..fd48cd0db1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2-expected.htm
@@ -0,0 +1,14 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ </head>
+ <body>
+ <div><canvas></canvas></div>
+ <p>This text should be visible, even though it's preceded by an unclosed canvas tag,
+ because of the &lt;/div&gt; that closes an element opened before the canvas.
+ There's nothing special about div; we get the same results with other types of
+ elements.
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2.htm
new file mode 100644
index 0000000000..fb329e73d6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-2.htm
@@ -0,0 +1,15 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ <link rel="match" href="unclosed-canvas-2-expected.htm">
+ <meta name="assert" content="Test what if canvas tag is unclosed in tag div" />
+ <script type="text/javascript"></script>
+ </head>
+ <body>
+ <div><canvas></div>
+ <p>This text should be visible, even though it's preceded by an unclosed canvas tag,
+ because of the &lt;/div&gt; that closes an element opened before the canvas.
+ There's nothing special about div; we get the same results with other types of elements.</p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3-expected.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3-expected.htm
new file mode 100644
index 0000000000..efd239b4fb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3-expected.htm
@@ -0,0 +1,13 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ </head>
+ <body>
+ <p>There should be no text below this, because the text is inside a canvas element
+ and the &lt;/div&gt; that's also inside the canvas element does not close an open
+ element. The canvas is never closed, and the rest of the body ends up inside it.
+ There's nothing special about div; we get the same results with other types of
+ elements.</p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3.htm
new file mode 100644
index 0000000000..8ffaa0f9eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-3.htm
@@ -0,0 +1,16 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ <link rel="match" href="unclosed-canvas-3-expected.htm">
+ <meta name="assert" content="Test what if canvas tag is unclosed in unclosed div" />
+ <script type="text/javascript"></script>
+ </head>
+ <body>
+ <p>There should be no text below this, because the text is inside a canvas element
+ and the &lt;/div&gt; that's also inside the canvas element does not close an open element.
+ The canvas is never closed, and the rest of the body ends up inside it.
+ There's nothing special about div; we get the same results with other types of elements.</p>
+ <canvas></div>This text should NOT be visible if JavaScript is enabled.
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4-expected.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4-expected.htm
new file mode 100644
index 0000000000..492449261e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4-expected.htm
@@ -0,0 +1,14 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ </head>
+ <body>
+ <p>There should be no text below this, because the text is inside a canvas element
+ and the &lt;/div&gt; that's also inside the canvas element does not close an open
+ element. The canvas is never closed, and the rest of the body ends up inside it.
+ There's nothing special about div; we get the same results with other types of
+ elements. The fact that the canvas tag uses XML self-closing syntax has no effect.
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4.htm b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4.htm
new file mode 100644
index 0000000000..aa5fd14438
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/unclosed-canvas-4.htm
@@ -0,0 +1,17 @@
+<!doctype HTML>
+<html>
+ <head>
+ <title>unclosed canvas tag in body</title>
+ <link rel="match" href="unclosed-canvas-4-expected.htm">
+ <meta name="assert" content="Test what if canvas tag is unclosed in body" />
+ <script type="text/javascript"></script>
+ </head>
+ <body>
+ <p>There should be no text below this, because the text is inside a canvas element
+ and the &lt;/div&gt; that's also inside the canvas element does not close an open element.
+ The canvas is never closed, and the rest of the body ends up inside it.
+ There's nothing special about div; we get the same results with other types of elements.
+ The fact that the canvas tag uses XML self-closing syntax has no effect.</p>
+ <canvas/></div>This text should NOT be visible if JavaScript is enabled.
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/ImageData-fidelity.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/ImageData-fidelity.html
new file mode 100644
index 0000000000..c2d158f893
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/ImageData-fidelity.html
@@ -0,0 +1,126 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async_test(function(t) {
+ var image = new Image();
+ // This image is 256 by 1 and contains an opaque grayscale ramp from 0 to 255.
+ // The image has no embedded color profile.
+ image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAABCAYAAAAx" +
+ "WXB3AAAAG0lEQVQ4T2NkYGD4z8jIyDCKR8NgNA2MvDQAAPiPA/5tZ8G+AAAAAElFTkSuQmCC";
+
+ image.onload = function() {
+ var canvas = document.createElement('canvas');
+ canvas.width = 256;
+ canvas.height = 1;
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(image, 0, 0);
+ var img = ctx.getImageData(0, 0, 256, 1);
+ t.step(function() {
+ for (var i = 0; i < 256; i++) {
+ assert_equals(img.data[4 * i], i, "red component");
+ assert_equals(img.data[4 * i + 1], i, "green component");
+ assert_equals(img.data[4 * i + 2], i, "blue component");
+ assert_equals(img.data[4 * i + 3], 255, "alpha component");
+ }
+ });
+ t.done();
+ }
+}, "Verify that drawImage->getImageData round trip preserves color values " +
+ "when image metadata has no color space and canvas uses the default " +
+ "color space.");
+
+async_test(function(t) {
+ var image = new Image();
+ // This image is 256 by 1 and contains an opaque grayscale ramp from 0 to 255.
+ // The image has an embedded sRGB color profile.
+ image.src =
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAABCAYAAAAxWXB3AAAA" +
+ "G0lEQVQ4T2NkYGD4z8jIyDCKR8NgNA2MvDQAAPiPA/5tZ8G+AAAAo3pUWHRSYXcgcHJvZm" +
+ "lsZSB0eXBlIEFQUDEAAHicZU5bCsMwDPv3KXoEv/I6TrampTC20ft/LE7WETJBkK1YQrCX" +
+ "ZzmP+/I+X9vxKLAYyCGoC9En77FCV10ROWNHrM8hUW7cQZ00V/026tDZMRKbUQYDt4lJJr" +
+ "2FxeCTJc5BV4svNE4Nxl1Tn8N1LCgMIoKJ2sHvo25sHfK/odYT02luCWMP+AA5M0KbNr61" +
+ "PwAAAABJRU5ErkJggg==";
+
+ image.onload = function() {
+ var canvas = document.createElement('canvas');
+ canvas.width = 256;
+ canvas.height = 1;
+ var ctx = canvas.getContext('2d', {colorSpace: 'srgb'});
+ ctx.drawImage(image, 0, 0);
+ var img = ctx.getImageData(0, 0, 256, 1);
+ t.step(function() {
+ for (var i = 0; i < 256; i++) {
+ assert_equals(img.data[4 * i], i, "red component");
+ assert_equals(img.data[4 * i + 1], i, "green component");
+ assert_equals(img.data[4 * i + 2], i, "blue component");
+ assert_equals(img.data[4 * i + 3], 255, "alpha component");
+ }
+ });
+ t.done();
+ }
+}, "Verify that drawImage->getImageData round trip preserves color values " +
+ "when image metadata has srgb color space and canvas uses the srgb " +
+ "color space.");
+
+async_test(function(t) {
+ var image = new Image();
+ // This image is 256 by 1 and contains an opaque grayscale ramp from 0 to 255.
+ // The image has no embedded color profile.
+ image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAABCAYAAAAx" +
+ "WXB3AAAAG0lEQVQ4T2NkYGD4z8jIyDCKR8NgNA2MvDQAAPiPA/5tZ8G+AAAAAElFTkSuQmCC";
+
+ image.onload = function() {
+ var canvas = document.createElement('canvas');
+ canvas.width = 256;
+ canvas.height = 1;
+ var ctx = canvas.getContext('2d', {colorSpace: 'srgb'});
+ ctx.drawImage(image, 0, 0);
+ var img = ctx.getImageData(0, 0, 256, 1);
+ t.step(function() {
+ for (var i = 0; i < 256; i++) {
+ assert_equals(img.data[4 * i], i, "red component");
+ assert_equals(img.data[4 * i + 1], i, "green component");
+ assert_equals(img.data[4 * i + 2], i, "blue component");
+ assert_equals(img.data[4 * i + 3], 255, "alpha component");
+ }
+ });
+ t.done();
+ }
+}, "Verify that drawImage->getImageData round trip preserves color values " +
+ "when image metadata has no color space and canvas uses the srgb " +
+ "color space.");
+
+
+async_test(function(t) {
+ var image = new Image();
+ // This image is 256 by 1 and contains an opaque grayscale ramp from 0 to 255.
+ // The image has an embedded sRGB color profile.
+ image.src =
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAABCAYAAAAxWXB3AAAA" +
+ "G0lEQVQ4T2NkYGD4z8jIyDCKR8NgNA2MvDQAAPiPA/5tZ8G+AAAAo3pUWHRSYXcgcHJvZm" +
+ "lsZSB0eXBlIEFQUDEAAHicZU5bCsMwDPv3KXoEv/I6TrampTC20ft/LE7WETJBkK1YQrCX" +
+ "ZzmP+/I+X9vxKLAYyCGoC9En77FCV10ROWNHrM8hUW7cQZ00V/026tDZMRKbUQYDt4lJJr" +
+ "2FxeCTJc5BV4svNE4Nxl1Tn8N1LCgMIoKJ2sHvo25sHfK/odYT02luCWMP+AA5M0KbNr61" +
+ "PwAAAABJRU5ErkJggg==";
+
+ image.onload = function() {
+ var canvas = document.createElement('canvas');
+ canvas.width = 256;
+ canvas.height = 1;
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(image, 0, 0);
+ var img = ctx.getImageData(0, 0, 256, 1);
+ t.step(function() {
+ for (var i = 0; i < 256; i++) {
+ assert_equals(img.data[4 * i], i, "red component");
+ assert_equals(img.data[4 * i + 1], i, "green component");
+ assert_equals(img.data[4 * i + 2], i, "blue component");
+ assert_equals(img.data[4 * i + 3], 255, "alpha component");
+ }
+ });
+ t.done();
+ }
+}, "Verify that drawImage->getImageData round trip preserves color values " +
+ "when image metadata has srgb color space and canvas uses the default " +
+ "color space.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html
new file mode 100644
index 0000000000..9b96b1a6d2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that drawing ImageBitmaps with different image Blob source bit depths
+// and color profiles into sRGB and Display P3 canvases works, by reading pixels
+// with getImageData() as sRGB and Display P3 values.
+for (let [filename, expectedPixels] of Object.entries(imageTests)) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ for (let cropSource of [false, true]) {
+ async_test(function(t) {
+ fetch(`resources/${filename}`)
+ .then(t.step_func(response => response.blob()))
+ .then(t.step_func(blob => (cropSource ? createImageBitmap(blob, 1, 1, 1, 1) : createImageBitmap(blob))))
+ .then(t.step_func_done(function(imageBitmap) {
+ let canvas = document.createElement("canvas");
+ canvas.width = 2;
+ canvas.height = 2;
+
+ let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
+ ctx.drawImage(imageBitmap, 0, 0);
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
+
+ let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+ }));
+ }, `${filename}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, cropSource=${cropSource}`);
+ }
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html
new file mode 100644
index 0000000000..0bd18e9beb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that drawing ImageBitmaps created from other ImageBitamps with different
+// image source bit depths and color profiles into sRGB and Display P3
+// canvases works, by reading pixels with getImageData() as sRGB and Display P3
+// values.
+for (let [filename, expectedPixels] of Object.entries(imageTests)) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ for (let cropSource of [false, true]) {
+ async_test(function(t) {
+ let image = new Image();
+ image.onload = t.step_func_done(function() {
+
+ let canvas = document.createElement("canvas");
+ canvas.width = 2;
+ canvas.height = 2;
+
+ let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
+
+ createImageBitmap(image).then(t.step_func(function(sourceImageBitmap) {
+ let imageBitmapPromise;
+ if (cropSource)
+ imageBitmapPromise = createImageBitmap(sourceImageBitmap, 1, 1, 1, 1);
+ else
+ imageBitmapPromise = createImageBitmap(sourceImageBitmap);
+
+ imageBitmapPromise.then(t.step_func_done(function(imageBitmap) {
+ ctx.drawImage(imageBitmap, 0, 0);
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
+
+ let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+ }));
+ }));
+ });
+ image.src = `resources/${filename}`;
+ }, `${filename}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, cropSource=${cropSource}`);
+ }
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageData.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageData.html
new file mode 100644
index 0000000000..2216b46dd8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageData.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that ImageBitmaps created from ImageData sources with different color
+// spaces can be drawn into sRGB and Display P3 canvases, by reading pixels with
+// getImageData() as sRGB and Display P3 values.
+function runTest(sourceColorSpace, destinationColorSpace, colors) {
+ for (let [sourceColorString, expectedColor] of Object.entries(colors)) {
+ for (let cropSource of [false, true]) {
+ async_test(function(t) {
+ let sourceColor = sourceColorString.split(",").map(x => +x);
+
+ let sourceImageData = new ImageData(4, 4, { colorSpace: sourceColorSpace });
+ for (let i = 0; i < 4 * 4 * 4; i += 4) {
+ for (let c = 0; c < 4; ++c)
+ sourceImageData.data[i + c] = sourceColor[c];
+ }
+
+ let imageBitmapPromise;
+ if (cropSource)
+ imageBitmapPromise = createImageBitmap(sourceImageData, 2, 2, 2, 2);
+ else
+ imageBitmapPromise = createImageBitmap(sourceImageData);
+
+ imageBitmapPromise.then(t.step_func_done(function(imageBitmap) {
+ let destination = document.createElement("canvas");
+ destination.width = 2;
+ destination.height = 2;
+
+ let destinationContext = destination.getContext("2d", { colorSpace: destinationColorSpace });
+ destinationContext.drawImage(imageBitmap, 0, 0);
+
+ let destinationImageData = destinationContext.getImageData(1, 1, 1, 1);
+
+ assert_true(pixelsApproximatelyEqual(destinationImageData.data, expectedColor), `Actual pixel value ${[...destinationImageData.data]} is approximately equal to ${expectedColor}.`);
+ }));
+ }, `Source ${sourceColorSpace}, destination ${destinationColorSpace}, color ${sourceColorString}, cropSource=${cropSource}`);
+ }
+ }
+}
+
+runTest("srgb", "display-p3", fromSRGBToDisplayP3);
+runTest("display-p3", "srgb", fromDisplayP3ToSRGB);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html
new file mode 100644
index 0000000000..f3156349ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that ImageBitmaps created from canvas sources with different color
+// spaces can be drawn into sRGB and Display P3 canvases, by reading pixels with
+// getImageData() as sRGB and Display P3 values.
+function runTest(sourceColorSpace, destinationColorSpace, colors) {
+ for (let [sourceColorString, expectedColor] of Object.entries(colors)) {
+ for (let cropSource of [false, true]) {
+ async_test(function(t) {
+ let source = document.createElement("canvas");
+ source.width = 4;
+ source.height = 4;
+
+ let sourceContext = source.getContext("2d", { colorSpace: sourceColorSpace });
+
+ let sourceColor = sourceColorString.split(",").map(x => +x);
+
+ let sourceImageData = new ImageData(4, 4, { colorSpace: sourceColorSpace });
+ for (let i = 0; i < 4 * 4 * 4; i += 4) {
+ for (let c = 0; c < 4; ++c)
+ sourceImageData.data[i + c] = sourceColor[c];
+ }
+ sourceContext.putImageData(sourceImageData, 0, 0);
+
+ let imageBitmapPromise;
+ if (cropSource)
+ imageBitmapPromise = createImageBitmap(source, 2, 2, 2, 2);
+ else
+ imageBitmapPromise = createImageBitmap(source);
+
+ imageBitmapPromise.then(t.step_func_done(function(imageBitmap) {
+ let destination = document.createElement("canvas");
+ destination.width = 2;
+ destination.height = 2;
+
+ let destinationContext = destination.getContext("2d", { colorSpace: destinationColorSpace });
+ destinationContext.drawImage(imageBitmap, 0, 0);
+
+ let destinationImageData = destinationContext.getImageData(1, 1, 1, 1);
+
+ assert_true(pixelsApproximatelyEqual(destinationImageData.data, expectedColor), `Actual pixel value ${[...destinationImageData.data]} is approximately equal to ${expectedColor}.`);
+ }));
+ }, `Source ${sourceColorSpace}, destination ${destinationColorSpace}, color ${sourceColorString}, cropSource=${cropSource}`);
+ }
+ }
+}
+
+runTest("srgb", "display-p3", fromSRGBToDisplayP3);
+runTest("display-p3", "srgb", fromDisplayP3ToSRGB);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html
new file mode 100644
index 0000000000..cf4f38f8db
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that drawing structured cloned ImageBitmaps with different image source
+// bit depths and color profiles into sRGB and Display P3 canvases works, by
+// reading pixels with getImageData() as sRGB and Display P3 values.
+
+let nextTestID = 0;
+
+class Test {
+ constructor(testConfiguration) {
+ Object.assign(this, testConfiguration);
+ this.testID = nextTestID++;
+ }
+
+ run() {
+ let self = this;
+ async_test(function(t) {
+ self.t = t;
+ self.image = new Image();
+ self.image.onload = t.step_func(self.onImageLoaded.bind(self));
+ self.image.src = `resources/${self.filename}`;
+ }, `${this.filename}, Context ${this.contextColorSpace}, ImageData ${this.imageDataColorSpace}, cropSource=${this.cropSource}`);
+ }
+
+ onImageLoaded() {
+ let imageBitmapPromise;
+ if (this.cropSource)
+ imageBitmapPromise = createImageBitmap(this.image, 1, 1, 1, 1);
+ else
+ imageBitmapPromise = createImageBitmap(this.image);
+ imageBitmapPromise.then(this.t.step_func(this.onImageBitmapCreated.bind(this)));
+ }
+
+ onImageBitmapCreated(imageBitmap) {
+ window.addEventListener("message", this.t.step_func(this.onMessage.bind(this)));
+ window.postMessage({ imageBitmap, testID: this.testID });
+ }
+
+ onMessage(message) {
+ if (message.data.testID != this.testID)
+ return;
+
+ let canvas = document.createElement("canvas");
+ canvas.width = 2;
+ canvas.height = 2;
+
+ let ctx = canvas.getContext("2d", { colorSpace: this.contextColorSpace });
+ ctx.drawImage(message.data.imageBitmap, 0, 0);
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: this.imageDataColorSpace });
+
+ let expected = this.expectedPixels[`${this.contextColorSpace} ${this.imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+
+ this.t.done();
+ }
+}
+
+for (let [filename, expectedPixels] of Object.entries(imageTests)) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ for (let cropSource of [false, true])
+ new Test({ filename, expectedPixels, contextColorSpace, imageDataColorSpace, cropSource }).run();
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html
new file mode 100644
index 0000000000..e7e85c915d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that drawing ImageBitmaps with different image source bit depths and
+// color profiles into sRGB and Display P3 canvases works, by reading pixels
+// with getImageData() as sRGB and Display P3 values.
+for (let [filename, expectedPixels] of Object.entries(imageTests)) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ for (let cropSource of [false, true]) {
+ async_test(function(t) {
+ let image = new Image();
+ image.onload = t.step_func(function() {
+
+ let canvas = document.createElement("canvas");
+ canvas.width = 2;
+ canvas.height = 2;
+
+ let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
+
+ let imageBitmapPromise;
+ if (cropSource)
+ imageBitmapPromise = createImageBitmap(image, 1, 1, 1, 1);
+ else
+ imageBitmapPromise = createImageBitmap(image);
+
+ imageBitmapPromise.then(t.step_func_done(function(imageBitmap) {
+ ctx.drawImage(imageBitmap, 0, 0);
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
+
+ let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+ }));
+ });
+ image.src = `resources/${filename}`;
+ }, `${filename}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, cropSource=${cropSource}`);
+ }
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html
new file mode 100644
index 0000000000..3e86bb5596
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<body>
+<script>
+// Test that drawing ImageBitmaps with different video source color profiles
+// into sRGB and Display P3 canvases works, by reading pixels with
+// getImageData() as sRGB and Display P3 values.
+for (let [filenameBase, expectedPixels] of Object.entries(videoTests)) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ for (let cropSource of [false, true]) {
+ promise_test(async function(t) {
+
+ let video = document.createElement("video");
+ for (let format of ["mp4", "webm"]) {
+ let source = document.createElement("source");
+ source.src = `resources/${filenameBase}.${format}`;
+ source.type = `video/${format}`;
+ video.append(source);
+ }
+
+ let loadedData = new Promise(resolver => video.onloadeddata = resolver);
+
+ document.body.append(video);
+ await video.play();
+ await loadedData;
+ await new Promise(requestAnimationFrame);
+
+ let imageBitmap;
+ if (cropSource)
+ imageBitmap = await createImageBitmap(video, 1, 1, 1, 1);
+ else
+ imageBitmap = await createImageBitmap(video);
+
+ video.remove();
+
+ let canvas = document.createElement("canvas");
+ canvas.width = 2;
+ canvas.height = 2;
+
+ let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
+
+ ctx.drawImage(imageBitmap, 0, 0);
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
+
+ let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+
+ }, `${filenameBase}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, cropSource=${cropSource}`);
+ }
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html
new file mode 100644
index 0000000000..1b04cde779
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<body>
+<script>
+// Test that drawing videos with different color spaces into sRGB and Display P3
+// canvases works, by reading pixels with getImageData() as sRGB and Display P3
+// values.
+for (let [filenameBase, expectedPixels] of Object.entries(videoTests)) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ for (let scaleImage of [false, true]) {
+ promise_test(async function(t) {
+
+ let video = document.createElement("video");
+ for (let format of ["mp4", "webm"]) {
+ let source = document.createElement("source");
+ source.src = `resources/${filenameBase}.${format}`;
+ source.type = `video/${format}`;
+ video.append(source);
+ }
+
+ let loadedData = new Promise(resolver => video.onloadeddata = resolver);
+
+ document.body.append(video);
+ await video.play();
+ await loadedData;
+ await new Promise(requestAnimationFrame);
+
+ let canvas = document.createElement("canvas");
+ canvas.width = 2;
+ canvas.height = 2;
+
+ let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
+ if (scaleImage)
+ ctx.drawImage(video, 0, 0, 10, 10);
+ else
+ ctx.drawImage(video, 0, 0);
+ video.remove();
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
+
+ let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+
+ }, `${filenameBase}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, scaleImage=${scaleImage}`);
+ }
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html
new file mode 100644
index 0000000000..35ee91343d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that drawing images with different bit depths and color profiles into
+// sRGB and Display P3 canvases works, by reading pixels with getImageData()
+// as sRGB and Display P3 values.
+for (let [filename, expectedPixels] of Object.entries({...imageTests, ...svgImageTests})) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ for (let scaleImage of [false, true]) {
+ async_test(function(t) {
+ let image = new Image();
+ image.onload = t.step_func_done(function() {
+
+ let canvas = document.createElement("canvas");
+ canvas.width = 2;
+ canvas.height = 2;
+
+ let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
+ if (scaleImage)
+ ctx.drawImage(image, 0, 0, 10, 10);
+ else
+ ctx.drawImage(image, 0, 0);
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
+
+ let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+
+ t.done();
+
+ });
+ image.src = `resources/${filename}`;
+ }, `${filename}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, scaleImage=${scaleImage}`);
+ }
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html
new file mode 100644
index 0000000000..2b9fb9b8f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that patterns created from canvas sources with different color spaces
+// can be drawn into sRGB and Display P3 canvases, by reading pixels with
+// getImageData() as sRGB and Display P3 values.
+function runTest(sourceColorSpace, destinationColorSpace, colors) {
+ for (let [sourceColorString, expectedColor] of Object.entries(colors)) {
+ test(function() {
+ let source = document.createElement("canvas");
+ source.width = 2;
+ source.height = 2;
+
+ let sourceContext = source.getContext("2d", { colorSpace: sourceColorSpace });
+
+ let sourceColor = sourceColorString.split(",").map(x => +x);
+
+ let sourceImageData = new ImageData(2, 2, { colorSpace: sourceColorSpace });
+ for (let i = 0; i < 2 * 2 * 4; i += 4) {
+ for (let c = 0; c < 4; ++c)
+ sourceImageData.data[i + c] = sourceColor[c];
+ }
+ sourceContext.putImageData(sourceImageData, 0, 0);
+
+ let destination = document.createElement("canvas");
+ destination.width = 4;
+ destination.height = 4;
+
+ let destinationContext = destination.getContext("2d", { colorSpace: destinationColorSpace });
+ destinationContext.fillStyle = destinationContext.createPattern(source, "repeat");
+ destinationContext.fillRect(0, 0, 4, 4);
+
+ let destinationImageData = destinationContext.getImageData(2, 2, 1, 1);
+
+ assert_true(pixelsApproximatelyEqual(destinationImageData.data, expectedColor), `Actual pixel value ${[...destinationImageData.data]} is approximately equal to ${expectedColor}.`);
+ }, `Source ${sourceColorSpace}, destination ${destinationColorSpace}, color ${sourceColorString}`);
+ }
+}
+
+runTest("srgb", "display-p3", fromSRGBToDisplayP3);
+runTest("display-p3", "srgb", fromDisplayP3ToSRGB);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html
new file mode 100644
index 0000000000..75a8392c02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="canvas-display-p3.js"></script>
+<script>
+// Test that patterns created from images with different bit depths and color
+// profiles into can be drawn into sRGB and Display P3 canvases, by reading
+// pixels with getImageData() as sRGB and Display P3 values.
+for (let [filename, expectedPixels] of Object.entries(imageTests)) {
+ for (let contextColorSpace of ["srgb", "display-p3"]) {
+ for (let imageDataColorSpace of ["srgb", "display-p3"]) {
+ async_test(function(t) {
+ let image = new Image();
+ image.onload = t.step_func_done(function() {
+
+ let canvas = document.createElement("canvas");
+ canvas.width = 4;
+ canvas.height = 4;
+
+ let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
+ ctx.fillStyle = ctx.createPattern(image, "repeat");
+ ctx.fillRect(0, 0, 4, 4);
+
+ let imageData = ctx.getImageData(2, 2, 1, 1, { colorSpace: imageDataColorSpace });
+
+ let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
+ assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
+
+ t.done();
+
+ });
+ image.src = `resources/${filename}`;
+ }, `${filename}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}`);
+ }
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html
new file mode 100644
index 0000000000..2b1447437d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+// Test that creating canvas contexts and ImageData objects respect the
+// requested color space.
+
+for (let contextColorSpace of [undefined, "srgb", "display-p3"]) {
+ for (let imageDataColorSpace of [undefined, "srgb", "display-p3"]) {
+ test(function() {
+ let contextSettings = { };
+ if (contextColorSpace)
+ contextSettings.colorSpace = contextColorSpace;
+ let resolvedContextColorSpace = contextColorSpace || "srgb";
+
+ let canvas = document.createElement("canvas");
+ let ctx = canvas.getContext("2d", contextSettings);
+ assert_equals(ctx.getContextAttributes().colorSpace, resolvedContextColorSpace, `CanvasRenderingContext2DSettings.colorSpace when set to ${contextColorSpace}`);
+
+ let imageDataSettings = { };
+ if (imageDataColorSpace)
+ imageDataSettings.colorSpace = imageDataColorSpace;
+ let resolvedImageDataColorSpace = imageDataColorSpace || resolvedContextColorSpace;
+
+ let imageData = ctx.getImageData(0, 0, 1, 1, imageDataSettings);
+ assert_equals(imageData.colorSpace, resolvedImageDataColorSpace, `getImageData() colorSpace when set to ${imageDataColorSpace}`);
+
+ imageData = ctx.createImageData(1, 1, imageDataSettings);
+ assert_equals(imageData.colorSpace, resolvedImageDataColorSpace, `createImageData() colorSpace when set to ${imageDataColorSpace}`);
+
+ imageData = ctx.createImageData(imageData);
+ assert_equals(imageData.colorSpace, resolvedImageDataColorSpace, `Cloned ImageData colorSpace when set to ${imageDataColorSpace}`);
+ }, `Context ${contextColorSpace}, ImageData ${imageDataColorSpace}`);
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3.js b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3.js
new file mode 100644
index 0000000000..c6ee97b788
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3.js
@@ -0,0 +1,283 @@
+// Each PNG:
+// * is 2x2 and has a single color
+// * has a filename that indicates its contents:
+// <embedded-profile>-<8-or-16-bit-color-value>.png
+// * was generated using ImageMagick commands like:
+// convert -size 2x2 xc:'#BB0000FF' -profile Display-P3.icc Display-P3-BB0000FF.png
+// convert -size 2x2 xc:'#BBBC00000000FFFF' -profile Adobe-RGB.icc Adobe-RGB-BBBC00000000FFFF.png
+
+// Top level key is the image filename. Second level key is the pair of
+// CanvasRenderingContext2DSettings.colorSpace and ImageDataSettings.colorSpace.
+const imageTests = {
+ // 8 bit source images
+
+ "sRGB-FF0000FF.png": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [234, 51, 35, 255],
+ },
+ "sRGB-FF0000CC.png": {
+ "srgb srgb": [255, 0, 0, 204],
+ "srgb display-p3": [234, 51, 35, 204],
+ "display-p3 srgb": [255, 0, 0, 204],
+ "display-p3 display-p3": [234, 51, 35, 204],
+ },
+ "sRGB-BB0000FF.png": {
+ "srgb srgb": [187, 0, 0, 255],
+ "srgb display-p3": [171, 35, 23, 255],
+ "display-p3 srgb": [187, 1, 0, 255],
+ "display-p3 display-p3": [171, 35, 23, 255],
+ },
+ "sRGB-BB0000CC.png": {
+ "srgb srgb": [187, 0, 0, 204],
+ "srgb display-p3": [171, 35, 23, 204],
+ "display-p3 srgb": [187, 1, 0, 204],
+ "display-p3 display-p3": [171, 35, 23, 204],
+ },
+
+ "Display-P3-FF0000FF.png": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [255, 0, 0, 255],
+ },
+ "Display-P3-FF0000CC.png": {
+ "srgb srgb": [255, 0, 0, 204],
+ "srgb display-p3": [234, 51, 35, 204],
+ "display-p3 srgb": [255, 0, 0, 204],
+ "display-p3 display-p3": [255, 0, 0, 204],
+ },
+ "Display-P3-BB0000FF.png": {
+ "srgb srgb": [205, 0, 0, 255],
+ "srgb display-p3": [188, 39, 26, 255],
+ "display-p3 srgb": [205, 0, 0, 255],
+ "display-p3 display-p3": [187, 0, 0, 255],
+ },
+ "Display-P3-BB0000CC.png": {
+ "srgb srgb": [205, 0, 0, 204],
+ "srgb display-p3": [188, 39, 26, 204],
+ "display-p3 srgb": [205, 0, 0, 204],
+ "display-p3 display-p3": [187, 0, 0, 204],
+ },
+
+ "Adobe-RGB-FF0000FF.png": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 19, 11, 255],
+ "display-p3 display-p3": [255, 61, 43, 255],
+ },
+ "Adobe-RGB-FF0000CC.png": {
+ "srgb srgb": [255, 0, 0, 204],
+ "srgb display-p3": [234, 51, 35, 204],
+ "display-p3 srgb": [255, 19, 11, 204],
+ "display-p3 display-p3": [255, 61, 43, 204],
+ },
+ "Adobe-RGB-BB0000FF.png": {
+ "srgb srgb": [219, 0, 0, 255],
+ "srgb display-p3": [201, 42, 29, 255],
+ "display-p3 srgb": [219, 0, 1, 255],
+ "display-p3 display-p3": [201, 42, 29, 255],
+ },
+ "Adobe-RGB-BB0000CC.png": {
+ "srgb srgb": [219, 0, 0, 204],
+ "srgb display-p3": [201, 42, 29, 204],
+ "display-p3 srgb": [219, 0, 1, 204],
+ "display-p3 display-p3": [201, 42, 29, 204],
+ },
+
+ "Generic-CMYK-FF000000.jpg": {
+ "srgb srgb": [0, 163, 218, 255],
+ "srgb display-p3": [72, 161, 213, 255],
+ "display-p3 srgb": [0, 163, 218, 255],
+ "display-p3 display-p3": [0, 160, 213, 255],
+ },
+ "Generic-CMYK-BE000000.jpg": {
+ "srgb srgb": [0, 180, 223, 255],
+ "srgb display-p3": [80, 177, 219, 255],
+ "display-p3 srgb": [0, 180, 223, 255],
+ "display-p3 display-p3": [65, 177, 219, 255],
+ },
+
+ // 16 bit source images
+
+ "sRGB-FFFF00000000FFFF.png": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [234, 51, 35, 255],
+ },
+ "sRGB-FFFF00000000CCCC.png": {
+ "srgb srgb": [255, 0, 0, 204],
+ "srgb display-p3": [234, 51, 35, 204],
+ "display-p3 srgb": [255, 0, 0, 204],
+ "display-p3 display-p3": [234, 51, 35, 204],
+ },
+ "sRGB-BBBC00000000FFFF.png": {
+ "srgb srgb": [187, 0, 0, 255],
+ "srgb display-p3": [171, 35, 23, 255],
+ "display-p3 srgb": [187, 1, 0, 255],
+ "display-p3 display-p3": [171, 35, 23, 255],
+ },
+ "sRGB-BBBC00000000CCCC.png": {
+ "srgb srgb": [187, 0, 0, 204],
+ "srgb display-p3": [171, 35, 23, 204],
+ "display-p3 srgb": [187, 1, 0, 204],
+ "display-p3 display-p3": [171, 35, 23, 204],
+ },
+
+ "Display-P3-FFFF00000000FFFF.png": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [255, 0, 0, 255],
+ },
+ "Display-P3-FFFF00000000CCCC.png": {
+ "srgb srgb": [255, 0, 0, 204],
+ "srgb display-p3": [234, 51, 35, 204],
+ "display-p3 srgb": [255, 0, 0, 204],
+ "display-p3 display-p3": [255, 0, 0, 204],
+ },
+ "Display-P3-BBBC00000000FFFF.png": {
+ "srgb srgb": [205, 0, 0, 255],
+ "srgb display-p3": [188, 39, 26, 255],
+ "display-p3 srgb": [205, 0, 0, 255],
+ "display-p3 display-p3": [187, 0, 0, 255],
+ },
+ "Display-P3-BBBC00000000CCCC.png": {
+ "srgb srgb": [205, 0, 0, 204],
+ "srgb display-p3": [188, 39, 26, 204],
+ "display-p3 srgb": [205, 0, 0, 204],
+ "display-p3 display-p3": [187, 0, 0, 204],
+ },
+
+ "Adobe-RGB-FFFF00000000FFFF.png": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 19, 11, 255],
+ "display-p3 display-p3": [255, 61, 43, 255],
+ },
+ "Adobe-RGB-FFFF00000000CCCC.png": {
+ "srgb srgb": [255, 0, 0, 204],
+ "srgb display-p3": [234, 51, 35, 204],
+ "display-p3 srgb": [255, 19, 11, 204],
+ "display-p3 display-p3": [255, 61, 43, 204],
+ },
+ "Adobe-RGB-BBBC00000000FFFF.png": {
+ "srgb srgb": [219, 0, 0, 255],
+ "srgb display-p3": [201, 42, 29, 255],
+ "display-p3 srgb": [219, 0, 1, 255],
+ "display-p3 display-p3": [201, 42, 29, 255],
+ },
+ "Adobe-RGB-BBBC00000000CCCC.png": {
+ "srgb srgb": [219, 0, 0, 204],
+ "srgb display-p3": [201, 42, 29, 204],
+ "display-p3 srgb": [219, 0, 1, 204],
+ "display-p3 display-p3": [201, 42, 29, 204],
+ },
+};
+
+const svgImageTests = {
+ // SVG source images
+
+ "sRGB-FF0000.svg": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [234, 51, 35, 255],
+ },
+ "sRGB-BB0000.svg": {
+ "srgb srgb": [187, 0, 0, 255],
+ "srgb display-p3": [171, 35, 23, 255],
+ "display-p3 srgb": [187, 1, 0, 255],
+ "display-p3 display-p3": [171, 35, 23, 255],
+ },
+
+ "Display-P3-1-0-0.svg": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [255, 0, 0, 255],
+ },
+ "Display-P3-0.7333-0-0.svg": {
+ "srgb srgb": [205, 0, 0, 255],
+ "srgb display-p3": [188, 39, 26, 255],
+ "display-p3 srgb": [205, 0, 0, 255],
+ "display-p3 display-p3": [187, 0, 0, 255],
+ },
+};
+
+// Each video:
+// * is 300x200 and has a single color
+// * has a filename base that indicates its contents:
+//
+// <color-space>-<8-or-10-bit-color-value>
+//
+// * was generated using commands like:
+//
+// W=300 H=200 Y=3F Cb=66 Cr=F0 ; \
+// perl -e "print pack('c', 0x$Y) x ($W * $H), pack('c', 0x$Cb) x ($W * $H / 4), pack('c', 0x$Cr) x ($W * $H / 4)" | \
+// ffmpeg -f rawvideo -pix_fmt yuv420p -s:v ${W}x$H -r 25 -i - -pix_fmt yuv420p -colorspace bt709 -color_primaries bt709 -color_trc iec61966_2_1 sRGB-FF0100.webm
+//
+// W=300 H=200 Y=0BB Cb=1BD Cr=2EF ; \
+// perl -e "print pack('s', 0x$Y) x ($W * $H), pack('s', 0x$Cb) x ($W * $H / 4), pack('s', 0x$Cr) x ($W * $H / 4)" | \
+// ffmpeg -f rawvideo -pix_fmt yuv420p10le -s:v ${W}x$H -r 25 -i - -c:v libx265 -vtag hvc1 -pix_fmt yuv420p10le -colorspace bt2020nc -color_primaries bt2020 -color_trc bt2020-10 Rec2020-222000000.mp4
+//
+// W=300 H=200 Y=0BB Cb=1BD Cr=2EF ; \
+// perl -e "print pack('s', 0x$Y) x ($W * $H), pack('s', 0x$Cb) x ($W * $H / 4), pack('s', 0x$Cr) x ($W * $H / 4)" | \
+// ffmpeg -f rawvideo -pix_fmt yuv420p10le -s:v ${W}x$H -r 25 -i - -vcodec libvpx-vp9 -profile:v 2 -pix_fmt yuv420p10le -colorspace bt2020nc -color_primaries bt2020 -color_trc bt2020-10 Rec2020-222000000.webm
+//
+// where the Y'CbCr values were computed using https://jdashg.github.io/misc/colors/from-coeffs.html.
+const videoTests = {
+ // Rec.709 Y'CbCr (0x3F, 0x66, 0xF0) = sRGB (0xFF, 0x01, 0x00)
+ "sRGB-FF0100": {
+ "srgb srgb": [255, 1, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [234, 51, 35, 255],
+ },
+ // Rec.709 Y'CbCr (0x32, 0x6D, 0xD2) = sRGB (0xBB, 0x00, 0x00)
+ "sRGB-BB0000": {
+ "srgb srgb": [187, 0, 0, 255],
+ "srgb display-p3": [171, 35, 23, 255],
+ "display-p3 srgb": [187, 1, 0, 255],
+ "display-p3 display-p3": [171, 35, 23, 255],
+ },
+
+ // 10 bit Rec.2020 Y'CbCr (0x126, 0x183, 0x3C0) = Rec.2020 (0x3FF, 0x000, 0x000)
+ "Rec2020-3FF000000": {
+ "srgb srgb": [255, 0, 0, 255],
+ "srgb display-p3": [234, 51, 35, 255],
+ "display-p3 srgb": [255, 0, 0, 255],
+ "display-p3 display-p3": [255, 0, 9, 255],
+ },
+ // 10 bit Rec.2020 Y'CbCr (0x0BB, 0x1BD, 0x2EF) = Rec.2020 (0x222, 0x000, 0x000)
+ "Rec2020-222000000": {
+ "srgb srgb": [186, 0, 0, 255],
+ "srgb display-p3": [170, 34, 23, 255],
+ "display-p3 srgb": [186, 0, 0, 255],
+ "display-p3 display-p3": [169, 0, 3, 255],
+ },
+};
+
+const fromSRGBToDisplayP3 = {
+ "255,0,0,255": [234, 51, 35, 255],
+ "255,0,0,204": [234, 51, 35, 204],
+ "187,0,0,255": [171, 35, 23, 255],
+ "187,0,0,204": [171, 35, 23, 204],
+};
+
+const fromDisplayP3ToSRGB = {
+ "255,0,0,255": [255, 0, 0, 255],
+ "255,0,0,204": [255, 0, 0, 204],
+ "187,0,0,255": [205, 0, 0, 255],
+ "187,0,0,204": [205, 0, 0, 204],
+};
+
+function pixelsApproximatelyEqual(p1, p2) {
+ for (let i = 0; i < 4; ++i) {
+ if (Math.abs(p1[i] - p2[i]) > 3)
+ return false;
+ }
+ return true;
+}
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/imagedata-no-color-settings-crash.html b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/imagedata-no-color-settings-crash.html
new file mode 100644
index 0000000000..b21eaf72ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/imagedata-no-color-settings-crash.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d',
+ {})
+ var dataFloat32 = new Float32Array(4);
+ var imageData = ctx.createImageData(dataFloat32, 1, 1,
+ {});
+ ctx.putImageData(imageData, 5, 5);
+ var data = ctx.getImageData(5,5,1,1).data;
+}, "Putting a float-32 ImageData with no color settings on a context 2D should not crash.");
+
+test(function() {
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d',
+ {})
+ var dataUint16 = new Uint16Array(4);
+ var imageData = ctx.createImageData(dataUint16, 1, 1,
+ {});
+ ctx.putImageData(imageData, 5, 5);
+ var data = ctx.getImageData(5,5,1,1).data;
+}, "Putting a uint-16 ImageData with no color settings on a context 2D should not crash.");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000CC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000CC.png
new file mode 100644
index 0000000000..9b3db7e22e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000CC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000FF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000FF.png
new file mode 100644
index 0000000000..78237d5a9d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BB0000FF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000CCCC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000CCCC.png
new file mode 100644
index 0000000000..3fbe7cadc0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000CCCC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000FFFF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000FFFF.png
new file mode 100644
index 0000000000..ab9b1bf5b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-BBBC00000000FFFF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000CC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000CC.png
new file mode 100644
index 0000000000..a83344933d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000CC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000FF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000FF.png
new file mode 100644
index 0000000000..3222c5e26f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FF0000FF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000CCCC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000CCCC.png
new file mode 100644
index 0000000000..60f1239943
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000CCCC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000FFFF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000FFFF.png
new file mode 100644
index 0000000000..c558eb10b3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Adobe-RGB-FFFF00000000FFFF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-0.7333-0-0.svg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-0.7333-0-0.svg
new file mode 100644
index 0000000000..2737814877
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-0.7333-0-0.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="2" height="2">
+ <rect width="2" height="2" style="fill: color(display-p3 0.7333 0 0);"/>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-1-0-0.svg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-1-0-0.svg
new file mode 100644
index 0000000000..5c1b07362a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-1-0-0.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="2" height="2">
+ <rect width="2" height="2" style="fill: color(display-p3 1 0 0);"/>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000CC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000CC.png
new file mode 100644
index 0000000000..2036aeae25
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000CC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000FF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000FF.png
new file mode 100644
index 0000000000..35347a3055
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BB0000FF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000CCCC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000CCCC.png
new file mode 100644
index 0000000000..87f11b5d97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000CCCC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000FFFF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000FFFF.png
new file mode 100644
index 0000000000..ea2f84caa1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-BBBC00000000FFFF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000CC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000CC.png
new file mode 100644
index 0000000000..8a0abc74dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000CC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000FF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000FF.png
new file mode 100644
index 0000000000..7b6d4a6150
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FF0000FF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000CCCC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000CCCC.png
new file mode 100644
index 0000000000..8a0abc74dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000CCCC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000FFFF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000FFFF.png
new file mode 100644
index 0000000000..7b6d4a6150
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Display-P3-FFFF00000000FFFF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-BE000000.jpg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-BE000000.jpg
new file mode 100644
index 0000000000..21eecaa25e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-BE000000.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-FF000000.jpg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-FF000000.jpg
new file mode 100644
index 0000000000..32f3b691e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Generic-CMYK-FF000000.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.mp4 b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.mp4
new file mode 100644
index 0000000000..71ad32c5f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.mp4
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.webm b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.webm
new file mode 100644
index 0000000000..5e4eae49dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.webm
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.mp4 b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.mp4
new file mode 100644
index 0000000000..0e2880a93a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.mp4
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.webm b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.webm
new file mode 100644
index 0000000000..4f28de8cea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.webm
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-p3d65.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-p3d65.png
new file mode 100644
index 0000000000..5eb3f6a15f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-p3d65.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-rec2020.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-rec2020.png
new file mode 100644
index 0000000000..b64db07379
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-rec2020.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-srgb.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-srgb.png
new file mode 100644
index 0000000000..bfbba8b8e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-semitransparent-srgb.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.avif b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.avif
new file mode 100644
index 0000000000..c3890c5cf6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.avif
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.bmp b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.bmp
new file mode 100644
index 0000000000..9c9561c704
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.bmp
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.ico b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.ico
new file mode 100644
index 0000000000..87e8ff45de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.ico
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.png
new file mode 100644
index 0000000000..bfbba8b8e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.webp b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.webp
new file mode 100644
index 0000000000..925646067a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb-transparent.webp
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.avif b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.avif
new file mode 100644
index 0000000000..c13b320ea8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.avif
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.bmp b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.bmp
new file mode 100644
index 0000000000..465d203d98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.bmp
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.gif b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.gif
new file mode 100644
index 0000000000..25bcefb2bf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.gif
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.ico b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.ico
new file mode 100644
index 0000000000..e5375826ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.ico
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.jpg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.jpg
new file mode 100644
index 0000000000..c4579e8f06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.png
new file mode 100644
index 0000000000..1b5876b5f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.svg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.svg
new file mode 100644
index 0000000000..0517130849
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.svg
@@ -0,0 +1,6 @@
+<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="0" y="0" width="10px" height="10px" fill="#9b1b1b"/>
+ <rect x="10" y="0" width="10px" height="10px" fill="#1b9b1b"/>
+ <rect x="0" y="10" width="10px" height="10px" fill="#1b1b9b"/>
+ <rect x="10" y="10" width="10px" height="10px" fill="#1b1b1b"/>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.webp b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.webp
new file mode 100644
index 0000000000..b7c0a421dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/pattern-srgb.webp
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_opaque.png
new file mode 100644
index 0000000000..c4496db19b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_transparent.png
new file mode 100644
index 0000000000..3b4cfda52c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_AdobeRGB_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_opaque.png
new file mode 100644
index 0000000000..e7a142cd2e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_transparent.png
new file mode 100644
index 0000000000..0b035317c8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_DisplayP3_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_opaque.png
new file mode 100644
index 0000000000..a1dc7ddb0d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_transparent.png
new file mode 100644
index 0000000000..be2eb1208e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_ProPhoto_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_opaque.png
new file mode 100644
index 0000000000..e2a2d14451
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_transparent.png
new file mode 100644
index 0000000000..960d7d8e75
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_Rec2020_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_opaque.png
new file mode 100644
index 0000000000..80cf9785eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_transparent.png
new file mode 100644
index 0000000000..3ec565f8c2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_AdobeRGB_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_opaque.png
new file mode 100644
index 0000000000..5f3134b79c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_transparent.png
new file mode 100644
index 0000000000..500a70eff8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_DisplayP3_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_opaque.png
new file mode 100644
index 0000000000..b5d0e07a7a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_transparent.png
new file mode 100644
index 0000000000..e4ec3e4454
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_ProPhoto_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_opaque.png
new file mode 100644
index 0000000000..c487d5846f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_transparent.png
new file mode 100644
index 0000000000..78fe202c0e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_Rec2020_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_opaque.png
new file mode 100644
index 0000000000..babf232a36
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_transparent.png
new file mode 100644
index 0000000000..3016404009
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_interlaced_sRGB_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_opaque.png
new file mode 100644
index 0000000000..8a665345e9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_transparent.png
new file mode 100644
index 0000000000..e51cda77c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_16bit_sRGB_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_opaque.png
new file mode 100644
index 0000000000..8b787b5c87
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_transparent.png
new file mode 100644
index 0000000000..727028e765
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_AdobeRGB_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_opaque.png
new file mode 100644
index 0000000000..fe8bdd4963
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_transparent.png
new file mode 100644
index 0000000000..b836afebed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_DisplayP3_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_opaque.png
new file mode 100644
index 0000000000..5ecd868606
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_transparent.png
new file mode 100644
index 0000000000..85a349dc1d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_ProPhoto_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_opaque.png
new file mode 100644
index 0000000000..599cd34040
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_transparent.png
new file mode 100644
index 0000000000..ecf65c3d46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_Rec2020_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_opaque.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_opaque.png
new file mode 100644
index 0000000000..9cab6d12e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_opaque.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_transparent.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_transparent.png
new file mode 100644
index 0000000000..5fa01e62c2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/png-16bit/2x2_8bit_sRGB_transparent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.mp4 b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.mp4
new file mode 100644
index 0000000000..59572f5138
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.mp4
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.svg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.svg
new file mode 100644
index 0000000000..2b785f8cf4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="2" height="2">
+ <rect width="2" height="2" style="fill: #BB0000;"/>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.webm b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.webm
new file mode 100644
index 0000000000..23a6364bdb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.webm
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000CC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000CC.png
new file mode 100644
index 0000000000..fe463486ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000CC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000FF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000FF.png
new file mode 100644
index 0000000000..be7009f613
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000FF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000CCCC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000CCCC.png
new file mode 100644
index 0000000000..5220ccb7a9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000CCCC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000FFFF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000FFFF.png
new file mode 100644
index 0000000000..416ef12986
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BBBC00000000FFFF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000.svg b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000.svg
new file mode 100644
index 0000000000..8798fdfc3a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="2" height="2">
+ <rect width="2" height="2" style="fill: #FF0000;"/>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000CC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000CC.png
new file mode 100644
index 0000000000..e86f64b71b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000CC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000FF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000FF.png
new file mode 100644
index 0000000000..22f33b14da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0000FF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.mp4 b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.mp4
new file mode 100644
index 0000000000..37a29f9f83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.mp4
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.webm b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.webm
new file mode 100644
index 0000000000..31b69af924
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.webm
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000CCCC.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000CCCC.png
new file mode 100644
index 0000000000..e86f64b71b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000CCCC.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000FFFF.png b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000FFFF.png
new file mode 100644
index 0000000000..22f33b14da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FFFF00000000FFFF.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.1.html
new file mode 100644
index 0000000000..85ebff4c0a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.angle.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.angle.1</h1>
+<p class="desc">arc() draws pi/2 .. -pi anticlockwise correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws pi/2 .. -pi anticlockwise correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.2.html
new file mode 100644
index 0000000000..7eefabd993
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.angle.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.angle.2</h1>
+<p class="desc">arc() draws -3pi/2 .. -pi anticlockwise correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws -3pi/2 .. -pi anticlockwise correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.3.html
new file mode 100644
index 0000000000..899c50dc90
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.angle.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.angle.3</h1>
+<p class="desc">arc() wraps angles mod 2pi when anticlockwise and end > start+2pi</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() wraps angles mod 2pi when anticlockwise and end > start+2pi");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.4.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.4.html
new file mode 100644
index 0000000000..3f1bd84d69
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.4.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.angle.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.angle.4</h1>
+<p class="desc">arc() draws a full circle when clockwise and end > start+2pi</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws a full circle when clockwise and end > start+2pi");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.5.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.5.html
new file mode 100644
index 0000000000..2373bd4f0a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.5.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.angle.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.angle.5</h1>
+<p class="desc">arc() wraps angles mod 2pi when clockwise and start > end+2pi</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() wraps angles mod 2pi when clockwise and start > end+2pi");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.6.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.6.html
new file mode 100644
index 0000000000..b0b03cff79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.angle.6.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.angle.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.angle.6</h1>
+<p class="desc">arc() draws a full circle when anticlockwise and start > end+2pi</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws a full circle when anticlockwise and start > end+2pi");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.default.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.default.html
new file mode 100644
index 0000000000..b52941fe3f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.default.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.default</h1>
+<p class="desc">arc() with missing last argument defaults to clockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with missing last argument defaults to clockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -Math.PI, Math.PI/2);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.empty.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.empty.html
new file mode 100644
index 0000000000..295ee4bbb2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.empty.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.empty</h1>
+<p class="desc">arc() with an empty path does not draw a straight line to the start point</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with an empty path does not draw a straight line to the start point");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.end.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.end.html
new file mode 100644
index 0000000000..a581a40e8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.end.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.end</h1>
+<p class="desc">arc() adds the end point of the arc to the subpath</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() adds the end point of the arc to the subpath");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(-100, 0);
+ ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.negative.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.negative.html
new file mode 100644
index 0000000000..fd81ebadcd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.negative.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.negative</h1>
+<p class="desc">arc() with negative radius throws INDEX_SIZE_ERR</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with negative radius throws INDEX_SIZE_ERR");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.arc(0, 0, -1, 0, 0, true); });
+ var path = new Path2D();
+ assert_throws_dom("INDEX_SIZE_ERR", function() { path.arc(10, 10, -5, 0, 1, false); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonempty.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonempty.html
new file mode 100644
index 0000000000..982829013d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonempty.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.nonempty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.nonempty</h1>
+<p class="desc">arc() with a non-empty path does draw a straight line to the start point</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with a non-empty path does draw a straight line to the start point");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonfinite.html
new file mode 100644
index 0000000000..a1b15e7a88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.nonfinite.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.nonfinite</h1>
+<p class="desc">arc() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, NaN, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, NaN, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, NaN, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, 0, Infinity, true);
+ ctx.arc(0, 0, 50, 0, -Infinity, true);
+ ctx.arc(0, 0, 50, 0, NaN, true);
+ ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, 0, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, 50, 0, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, 50, 0, Infinity, true);
+ ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, 0, Infinity, 0, Infinity, true);
+ ctx.arc(0, 0, 50, Infinity, Infinity, true);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.1.html
new file mode 100644
index 0000000000..951c9ae26c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.1.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.scale.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.scale.1</h1>
+<p class="desc">Non-uniformly scaled arcs are the right shape</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Non-uniformly scaled arcs are the right shape");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(2, 0.5);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(25, 50, 56, 0, 2*Math.PI, false);
+ ctx.fill();
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-25, 50);
+ ctx.arc(-25, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(75, 50);
+ ctx.arc(75, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, -25);
+ ctx.arc(25, -25, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, 125);
+ ctx.arc(25, 125, 24, 0, 2*Math.PI, false);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.2.html
new file mode 100644
index 0000000000..6b39e16222
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.scale.2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.scale.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.scale.2</h1>
+<p class="desc">Highly scaled arcs are the right shape</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Highly scaled arcs are the right shape");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(100, 100);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 1.2;
+ ctx.beginPath();
+ ctx.arc(0, 0, 0.6, 0, Math.PI/2, false);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html
new file mode 100644
index 0000000000..3bc81bd77a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.selfintersect.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.selfintersect.1</h1>
+<p class="desc">arc() with lineWidth > 2*radius is drawn sensibly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with lineWidth > 2*radius is drawn sensibly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(100, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html
new file mode 100644
index 0000000000..e3b14a782f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.selfintersect.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.selfintersect.2</h1>
+<p class="desc">arc() with lineWidth > 2*radius is drawn sensibly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with lineWidth > 2*radius is drawn sensibly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 180;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(100, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 97,1, 0,255,0,255);
+ _assertPixel(canvas, 97,2, 0,255,0,255);
+ _assertPixel(canvas, 97,3, 0,255,0,255);
+ _assertPixel(canvas, 2,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.1.html
new file mode 100644
index 0000000000..8a456841ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.1.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.shape.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.shape.1</h1>
+<p class="desc">arc() from 0 to pi does not draw anything in the wrong half</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() from 0 to pi does not draw anything in the wrong half");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 20,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.2.html
new file mode 100644
index 0000000000..f820eed761
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.shape.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.shape.2</h1>
+<p class="desc">arc() from 0 to pi draws stuff in the right half</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() from 0 to pi draws stuff in the right half");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 20,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.3.html
new file mode 100644
index 0000000000..aa08d44194
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.shape.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.shape.3</h1>
+<p class="desc">arc() from 0 to -pi/2 does not draw anything in the wrong quadrant</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() from 0 to -pi/2 does not draw anything in the wrong quadrant");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(0, 50, 50, 0, -Math.PI/2, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.4.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.4.html
new file mode 100644
index 0000000000..b00d4468f2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.shape.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.shape.4</h1>
+<p class="desc">arc() from 0 to -pi/2 draws stuff in the right quadrant</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() from 0 to -pi/2 draws stuff in the right quadrant");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 150;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 100, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.5.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.5.html
new file mode 100644
index 0000000000..f5574d2773
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.shape.5.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.shape.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.shape.5</h1>
+<p class="desc">arc() from 0 to 5pi does not draw crazy things</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() from 0 to 5pi does not draw crazy things");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(300, 0, 100, 0, 5*Math.PI, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.1.html
new file mode 100644
index 0000000000..6312efb3e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.twopie.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.twopie.1</h1>
+<p class="desc">arc() draws nothing when end = start + 2pi-e and anticlockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws nothing when end = start + 2pi-e and anticlockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.2.html
new file mode 100644
index 0000000000..132c2d38dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.twopie.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.twopie.2</h1>
+<p class="desc">arc() draws a full circle when end = start + 2pi-e and clockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws a full circle when end = start + 2pi-e and clockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.3.html
new file mode 100644
index 0000000000..204ed54a1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.twopie.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.twopie.3</h1>
+<p class="desc">arc() draws a full circle when end = start + 2pi+e and anticlockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws a full circle when end = start + 2pi+e and anticlockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.4.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.4.html
new file mode 100644
index 0000000000..d5535a7949
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.4.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.twopie.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.twopie.4</h1>
+<p class="desc">arc() draws nothing when end = start + 2pi+e and clockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws nothing when end = start + 2pi+e and clockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.5.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.5.html
new file mode 100644
index 0000000000..955a6c8743
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.5.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.twopie.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.twopie.5</h1>
+<p class="desc">arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ _assertPixel(canvas, 95,25, 0,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.6.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.6.html
new file mode 100644
index 0000000000..9420ecdc93
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.twopie.6.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.twopie.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.twopie.6</h1>
+<p class="desc">arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ _assertPixel(canvas, 5,25, 0,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.1.html
new file mode 100644
index 0000000000..2c93425b1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.zero.1</h1>
+<p class="desc">arc() draws nothing when startAngle = endAngle and anticlockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws nothing when startAngle = endAngle and anticlockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.2.html
new file mode 100644
index 0000000000..c290c2f32f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zero.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.zero.2</h1>
+<p class="desc">arc() draws nothing when startAngle = endAngle and clockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() draws nothing when startAngle = endAngle and clockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zeroradius.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zeroradius.html
new file mode 100644
index 0000000000..f75403b2f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arc.zeroradius.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arc.zeroradius</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arc.zeroradius</h1>
+<p class="desc">arc() with zero radius draws a line to the start point</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arc() with zero radius draws a line to the start point");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00'
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 0, 0, Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.1.html
new file mode 100644
index 0000000000..01c8091c46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.1.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.coincide.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.coincide.1</h1>
+<p class="desc">arcTo() has no effect if P0 = P1</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() has no effect if P0 = P1");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(0, 25, 50, 1000, 1);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.2.html
new file mode 100644
index 0000000000..d216949aae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.coincide.2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.coincide.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.coincide.2</h1>
+<p class="desc">arcTo() draws a straight line to P1 if P1 = P2</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() draws a straight line to P1 if P1 = P2");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.1.html
new file mode 100644
index 0000000000..e91e2e4b1b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.1.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.collinear.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.collinear.1</h1>
+<p class="desc">arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 200, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.2.html
new file mode 100644
index 0000000000..97b1339295
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.collinear.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.collinear.2</h1>
+<p class="desc">arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 10, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 110, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.3.html
new file mode 100644
index 0000000000..2f4394f038
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.collinear.3.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.collinear.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.collinear.3</h1>
+<p class="desc">arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 0, 25, 1);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, -200, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..2781bcbba3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the first control point is added (and nothing is drawn up to it)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arcTo(100, 50, 200, 50, 0.1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..f5da07c1c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.ensuresubpath.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the first control point is added</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the first control point is added");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arcTo(0, 25, 50, 250, 0.1); // adds (x1,y1), draws nothing
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.negative.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.negative.html
new file mode 100644
index 0000000000..0091ca2a67
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.negative.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.negative</h1>
+<p class="desc">arcTo() with negative radius throws an exception</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() with negative radius throws an exception");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.arcTo(0, 0, 0, 0, -1); });
+ var path = new Path2D();
+ assert_throws_dom("INDEX_SIZE_ERR", function() { path.arcTo(10, 10, 20, 20, -5); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.nonfinite.html
new file mode 100644
index 0000000000..0d7be1d360
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.nonfinite.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.nonfinite</h1>
+<p class="desc">arcTo() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arcTo(Infinity, 50, 0, 50, 0);
+ ctx.arcTo(-Infinity, 50, 0, 50, 0);
+ ctx.arcTo(NaN, 50, 0, 50, 0);
+ ctx.arcTo(0, Infinity, 0, 50, 0);
+ ctx.arcTo(0, -Infinity, 0, 50, 0);
+ ctx.arcTo(0, NaN, 0, 50, 0);
+ ctx.arcTo(0, 50, Infinity, 50, 0);
+ ctx.arcTo(0, 50, -Infinity, 50, 0);
+ ctx.arcTo(0, 50, NaN, 50, 0);
+ ctx.arcTo(0, 50, 0, Infinity, 0);
+ ctx.arcTo(0, 50, 0, -Infinity, 0);
+ ctx.arcTo(0, 50, 0, NaN, 0);
+ ctx.arcTo(0, 50, 0, 50, Infinity);
+ ctx.arcTo(0, 50, 0, 50, -Infinity);
+ ctx.arcTo(0, 50, 0, 50, NaN);
+ ctx.arcTo(Infinity, Infinity, 0, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, 50, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, 50, 0, Infinity, 0);
+ ctx.arcTo(Infinity, 50, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, 0, 50, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(0, Infinity, 0, Infinity, 0);
+ ctx.arcTo(0, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, 0, 50, Infinity);
+ ctx.arcTo(0, 50, Infinity, Infinity, 0);
+ ctx.arcTo(0, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, 50, Infinity, 50, Infinity);
+ ctx.arcTo(0, 50, 0, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.scale.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.scale.html
new file mode 100644
index 0000000000..6645f05260
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.scale.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.scale</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.scale</h1>
+<p class="desc">arcTo scales the curve, not just the control points</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo scales the curve, not just the control points");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.scale(0.1, 1);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-1000, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve1.html
new file mode 100644
index 0000000000..4617b2cbbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve1.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.shape.curve1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.shape.curve1</h1>
+<p class="desc">arcTo() curves in the right kind of shape</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() curves in the right kind of shape");
+_addTest(function(canvas, ctx) {
+
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 55,19, 0,255,0,255);
+ _assertPixel(canvas, 55,20, 0,255,0,255);
+ _assertPixel(canvas, 55,21, 0,255,0,255);
+ _assertPixel(canvas, 64,22, 0,255,0,255);
+ _assertPixel(canvas, 65,21, 0,255,0,255);
+ _assertPixel(canvas, 72,28, 0,255,0,255);
+ _assertPixel(canvas, 73,27, 0,255,0,255);
+ _assertPixel(canvas, 78,36, 0,255,0,255);
+ _assertPixel(canvas, 79,35, 0,255,0,255);
+ _assertPixel(canvas, 80,44, 0,255,0,255);
+ _assertPixel(canvas, 80,45, 0,255,0,255);
+ _assertPixel(canvas, 80,46, 0,255,0,255);
+ _assertPixel(canvas, 65,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve2.html
new file mode 100644
index 0000000000..bcc4326eea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.curve2.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.shape.curve2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.shape.curve2</h1>
+<p class="desc">arcTo() curves in the right kind of shape</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() curves in the right kind of shape");
+_addTest(function(canvas, ctx) {
+
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 55,19, 0,255,0,255);
+ _assertPixel(canvas, 55,20, 0,255,0,255);
+ _assertPixel(canvas, 55,21, 0,255,0,255);
+ _assertPixel(canvas, 64,22, 0,255,0,255);
+ _assertPixel(canvas, 65,21, 0,255,0,255);
+ _assertPixel(canvas, 72,28, 0,255,0,255);
+ _assertPixel(canvas, 73,27, 0,255,0,255);
+ _assertPixel(canvas, 78,36, 0,255,0,255);
+ _assertPixel(canvas, 79,35, 0,255,0,255);
+ _assertPixel(canvas, 80,44, 0,255,0,255);
+ _assertPixel(canvas, 80,45, 0,255,0,255);
+ _assertPixel(canvas, 80,46, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.end.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.end.html
new file mode 100644
index 0000000000..829c70f5f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.end.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.shape.end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.shape.end</h1>
+<p class="desc">arcTo() does not draw anything from P1 to P2</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() does not draw anything from P1 to P2");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.arcTo(-100, 25, 200, 25, 10);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.start.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.start.html
new file mode 100644
index 0000000000..0abeedf433
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.shape.start.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.shape.start</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.shape.start</h1>
+<p class="desc">arcTo() draws a straight line from P0 to P1</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() draws a straight line from P0 to P1");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(200, 25, 200, 50, 10);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.transformation.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.transformation.html
new file mode 100644
index 0000000000..5aa8562b1d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.transformation.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.transformation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.transformation</h1>
+<p class="desc">arcTo joins up to the last subpath point correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo joins up to the last subpath point correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.1.html
new file mode 100644
index 0000000000..bb2cc1d3e3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.1.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.zero.1</h1>
+<p class="desc">arcTo() with zero radius draws a straight line from P0 to P1</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() with zero radius draws a straight line from P0 to P1");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 100, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(0, -25);
+ ctx.arcTo(50, -25, 50, 50, 0);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.2.html
new file mode 100644
index 0000000000..d2eeee535d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.arcTo.zero.2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.arcTo.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.arcTo.zero.2</h1>
+<p class="desc">arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 50, 25, 0);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.beginPath.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.beginPath.html
new file mode 100644
index 0000000000..316f6af942
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.beginPath.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.beginPath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.beginPath</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.basic.html
new file mode 100644
index 0000000000..0c3d7f948b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.basic.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.bezierCurveTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.bezierCurveTo.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..ebcce3f48c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.bezierCurveTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.bezierCurveTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the first control point is added (and nothing is drawn up to it)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(100, 50, 200, 50, 200, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 95,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..c269b72d33
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.bezierCurveTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.bezierCurveTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the first control point is added</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the first control point is added");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(0, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.nonfinite.html
new file mode 100644
index 0000000000..6278a67283
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.nonfinite.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.bezierCurveTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.bezierCurveTo.nonfinite</h1>
+<p class="desc">bezierCurveTo() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("bezierCurveTo() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(-Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(NaN, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, -Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, NaN, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, -Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, NaN, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, -Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, NaN, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, -Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, NaN, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, -Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, NaN);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.scaled.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.scaled.html
new file mode 100644
index 0000000000..e7a5d8b524
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.scaled.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.bezierCurveTo.scaled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.bezierCurveTo.scaled</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-2, 3.1);
+ ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.shape.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.shape.html
new file mode 100644
index 0000000000..cbc2824425
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.bezierCurveTo.shape.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.bezierCurveTo.shape</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.bezierCurveTo.shape</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-2000, 3100);
+ ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.1.html
new file mode 100644
index 0000000000..a5515e4f7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.clip.basic.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.clip.basic.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.2.html
new file mode 100644
index 0000000000..27e1ad0b0c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.basic.2.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.clip.basic.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.clip.basic.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(-100, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.empty.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.empty.html
new file mode 100644
index 0000000000..17208ad797
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.empty.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.clip.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.clip.empty</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.intersect.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.intersect.html
new file mode 100644
index 0000000000..c1057f2645
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.intersect.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.clip.intersect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.clip.intersect</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50)
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.unaffected.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.unaffected.html
new file mode 100644
index 0000000000..66f0379602
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.unaffected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.clip.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.clip.unaffected</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.lineTo(0, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.1.html
new file mode 100644
index 0000000000..46e4db9b6c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.clip.winding.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.clip.winding.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.2.html
new file mode 100644
index 0000000000..9341353a8d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.clip.winding.2.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.clip.winding.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.clip.winding.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.clip();
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.empty.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.empty.html
new file mode 100644
index 0000000000..898cdc5fa6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.empty.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.closePath.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.closePath.empty</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.newline.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.newline.html
new file mode 100644
index 0000000000..07ec4b2a82
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.newline.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.closePath.newline</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.closePath.newline</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.closePath();
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.nextpoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.nextpoint.html
new file mode 100644
index 0000000000..648d7ad37a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.closePath.nextpoint.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.closePath.nextpoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.closePath.nextpoint</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -1000);
+ ctx.closePath();
+ ctx.lineTo(1000, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.ellipse.basics.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.ellipse.basics.html
new file mode 100644
index 0000000000..d46dc31d26
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.ellipse.basics.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.ellipse.basics</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.ellipse.basics</h1>
+<p class="desc">Verify canvas throws error when drawing ellipse with negative radii.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify canvas throws error when drawing ellipse with negative radii.");
+_addTest(function(canvas, ctx) {
+
+ ctx.ellipse(10, 10, 10, 5, 0, 0, 1, false);
+ ctx.ellipse(10, 10, 10, 0, 0, 0, 1, false);
+ ctx.ellipse(10, 10, -0, 5, 0, 0, 1, false);
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, -2, 5, 0, 0, 1, false); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, 0, -1.5, 0, 0, 1, false); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, -2, -5, 0, 0, 1, false); });
+ ctx.ellipse(80, 0, 10, 4294967277, Math.PI / -84, -Math.PI / 2147483436, false);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.basic.html
new file mode 100644
index 0000000000..010dbf43e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.fill.closed.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.fill.closed.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.unaffected.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.unaffected.html
new file mode 100644
index 0000000000..e00a6c8f55
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.closed.unaffected.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.fill.closed.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.fill.closed.unaffected</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 10,40, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.html
new file mode 100644
index 0000000000..08782ed11e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.fill.overlap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.fill.overlap</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.path.fill.overlap.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.rect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.rect(10, 10, 80, 30);
+ ctx.fill();
+
+ _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.png b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.png
new file mode 100644
index 0000000000..e2a35d48d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.overlap.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.add.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.add.html
new file mode 100644
index 0000000000..ef9a2a0f93
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.add.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.fill.winding.add</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.fill.winding.add</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.1.html
new file mode 100644
index 0000000000..eecf0198e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.1.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.fill.winding.subtract.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.fill.winding.subtract.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.2.html
new file mode 100644
index 0000000000..cf8b6a6ce9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.2.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.fill.winding.subtract.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.fill.winding.subtract.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.3.html
new file mode 100644
index 0000000000..e056e33003
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.fill.winding.subtract.3.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.fill.winding.subtract.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.fill.winding.subtract.3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(120, -20);
+ ctx.lineTo(120, 70);
+ ctx.lineTo(-20, 70);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.initial.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.initial.html
new file mode 100644
index 0000000000..a3de93a799
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.initial.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.initial</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.arc.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.arc.html
new file mode 100644
index 0000000000..bc4bc560e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.arc.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.arc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.arc</h1>
+<p class="desc">isPointInPath() works on arcs</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() works on arcs");
+_addTest(function(canvas, ctx) {
+
+ ctx.arc(50, 25, 10, 0, Math.PI, false);
+ _assertSame(ctx.isPointInPath(50, 10), false, "ctx.isPointInPath(50, 10)", "false");
+ _assertSame(ctx.isPointInPath(50, 20), false, "ctx.isPointInPath(50, 20)", "false");
+ _assertSame(ctx.isPointInPath(50, 30), true, "ctx.isPointInPath(50, 30)", "true");
+ _assertSame(ctx.isPointInPath(50, 40), false, "ctx.isPointInPath(50, 40)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), false, "ctx.isPointInPath(70, 30)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.1.html
new file mode 100644
index 0000000000..22562c60a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.1.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.basic.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.basic.1</h1>
+<p class="desc">isPointInPath() detects whether the point is inside the path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() detects whether the point is inside the path");
+_addTest(function(canvas, ctx) {
+
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), true, "ctx.isPointInPath(10, 10)", "true");
+ _assertSame(ctx.isPointInPath(30, 10), false, "ctx.isPointInPath(30, 10)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.2.html
new file mode 100644
index 0000000000..9fc1060df8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.2.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.basic.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.basic.2</h1>
+<p class="desc">isPointInPath() detects whether the point is inside the path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() detects whether the point is inside the path");
+_addTest(function(canvas, ctx) {
+
+ ctx.rect(20, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(30, 10), true, "ctx.isPointInPath(30, 10)", "true");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.html
new file mode 100644
index 0000000000..5e3edfcc80
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.basic.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.basic</h1>
+<p class="desc">Verify the winding rule in isPointInPath works for for rect path.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify the winding rule in isPointInPath works for for rect path.");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50), true, "ctx.isPointInPath(50, 50)", "true");
+ _assertSame(ctx.isPointInPath(NaN, 50), false, "ctx.isPointInPath(NaN, 50)", "false");
+ _assertSame(ctx.isPointInPath(50, NaN), false, "ctx.isPointInPath(50, NaN)", "false");
+
+ // Testing nonzero isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50, 'nonzero'), true, "ctx.isPointInPath(50, 50, 'nonzero')", "true");
+
+ // Testing evenodd isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50, 'evenodd'), false, "ctx.isPointInPath(50, 50, 'evenodd')", "false");
+
+ // Testing extremely large scale
+ ctx.save();
+ ctx.scale(Number.MAX_VALUE, Number.MAX_VALUE);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0, 'nonzero'), true, "ctx.isPointInPath(0, 0, 'nonzero')", "true");
+ _assertSame(ctx.isPointInPath(0, 0, 'evenodd'), true, "ctx.isPointInPath(0, 0, 'evenodd')", "true");
+ ctx.restore();
+
+ // Check with non-invertible ctm.
+ ctx.save();
+ ctx.scale(0, 0);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0, 'nonzero'), false, "ctx.isPointInPath(0, 0, 'nonzero')", "false");
+ _assertSame(ctx.isPointInPath(0, 0, 'evenodd'), false, "ctx.isPointInPath(0, 0, 'evenodd')", "false");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bezier.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bezier.html
new file mode 100644
index 0000000000..b2f2d23724
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bezier.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.bezier</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.bezier</h1>
+<p class="desc">isPointInPath() works on Bezier curves</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() works on Bezier curves");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(25, 25);
+ ctx.bezierCurveTo(50, -50, 50, 100, 75, 25);
+ _assertSame(ctx.isPointInPath(25, 20), false, "ctx.isPointInPath(25, 20)", "false");
+ _assertSame(ctx.isPointInPath(25, 30), false, "ctx.isPointInPath(25, 30)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), true, "ctx.isPointInPath(30, 20)", "true");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(40, 2), false, "ctx.isPointInPath(40, 2)", "false");
+ _assertSame(ctx.isPointInPath(40, 20), true, "ctx.isPointInPath(40, 20)", "true");
+ _assertSame(ctx.isPointInPath(40, 30), false, "ctx.isPointInPath(40, 30)", "false");
+ _assertSame(ctx.isPointInPath(40, 47), false, "ctx.isPointInPath(40, 47)", "false");
+ _assertSame(ctx.isPointInPath(45, 20), true, "ctx.isPointInPath(45, 20)", "true");
+ _assertSame(ctx.isPointInPath(45, 30), false, "ctx.isPointInPath(45, 30)", "false");
+ _assertSame(ctx.isPointInPath(55, 20), false, "ctx.isPointInPath(55, 20)", "false");
+ _assertSame(ctx.isPointInPath(55, 30), true, "ctx.isPointInPath(55, 30)", "true");
+ _assertSame(ctx.isPointInPath(60, 2), false, "ctx.isPointInPath(60, 2)", "false");
+ _assertSame(ctx.isPointInPath(60, 20), false, "ctx.isPointInPath(60, 20)", "false");
+ _assertSame(ctx.isPointInPath(60, 30), true, "ctx.isPointInPath(60, 30)", "true");
+ _assertSame(ctx.isPointInPath(60, 47), false, "ctx.isPointInPath(60, 47)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), true, "ctx.isPointInPath(70, 30)", "true");
+ _assertSame(ctx.isPointInPath(75, 20), false, "ctx.isPointInPath(75, 20)", "false");
+ _assertSame(ctx.isPointInPath(75, 30), false, "ctx.isPointInPath(75, 30)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bigarc.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bigarc.html
new file mode 100644
index 0000000000..77cb495137
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.bigarc.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.bigarc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.bigarc</h1>
+<p class="desc">isPointInPath() works on unclosed arcs larger than 2pi</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() works on unclosed arcs larger than 2pi");
+_addTest(function(canvas, ctx) {
+
+ ctx.arc(50, 25, 10, 0, 7, false);
+ _assertSame(ctx.isPointInPath(50, 10), false, "ctx.isPointInPath(50, 10)", "false");
+ _assertSame(ctx.isPointInPath(50, 20), true, "ctx.isPointInPath(50, 20)", "true");
+ _assertSame(ctx.isPointInPath(50, 30), true, "ctx.isPointInPath(50, 30)", "true");
+ _assertSame(ctx.isPointInPath(50, 40), false, "ctx.isPointInPath(50, 40)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), false, "ctx.isPointInPath(70, 30)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.edge.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.edge.html
new file mode 100644
index 0000000000..b00da5a2a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.edge.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.edge</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.edge</h1>
+<p class="desc">isPointInPath() counts points on the path as being inside</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() counts points on the path as being inside");
+_addTest(function(canvas, ctx) {
+
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0), true, "ctx.isPointInPath(0, 0)", "true");
+ _assertSame(ctx.isPointInPath(10, 0), true, "ctx.isPointInPath(10, 0)", "true");
+ _assertSame(ctx.isPointInPath(20, 0), true, "ctx.isPointInPath(20, 0)", "true");
+ _assertSame(ctx.isPointInPath(20, 10), true, "ctx.isPointInPath(20, 10)", "true");
+ _assertSame(ctx.isPointInPath(20, 20), true, "ctx.isPointInPath(20, 20)", "true");
+ _assertSame(ctx.isPointInPath(10, 20), true, "ctx.isPointInPath(10, 20)", "true");
+ _assertSame(ctx.isPointInPath(0, 20), true, "ctx.isPointInPath(0, 20)", "true");
+ _assertSame(ctx.isPointInPath(0, 10), true, "ctx.isPointInPath(0, 10)", "true");
+ _assertSame(ctx.isPointInPath(10, -0.01), false, "ctx.isPointInPath(10, -0.01)", "false");
+ _assertSame(ctx.isPointInPath(10, 20.01), false, "ctx.isPointInPath(10, 20.01)", "false");
+ _assertSame(ctx.isPointInPath(-0.01, 10), false, "ctx.isPointInPath(-0.01, 10)", "false");
+ _assertSame(ctx.isPointInPath(20.01, 10), false, "ctx.isPointInPath(20.01, 10)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.empty.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.empty.html
new file mode 100644
index 0000000000..3edfe01a2a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.empty.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.empty</h1>
+<p class="desc">isPointInPath() works when there is no path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() works when there is no path");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.isPointInPath(0, 0), false, "ctx.isPointInPath(0, 0)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.nonfinite.html
new file mode 100644
index 0000000000..4ef541a431
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.nonfinite.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.nonfinite</h1>
+<p class="desc">isPointInPath() returns false for non-finite arguments</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() returns false for non-finite arguments");
+_addTest(function(canvas, ctx) {
+
+ ctx.rect(-100, -50, 200, 100);
+ _assertSame(ctx.isPointInPath(Infinity, 0), false, "ctx.isPointInPath(Infinity, 0)", "false");
+ _assertSame(ctx.isPointInPath(-Infinity, 0), false, "ctx.isPointInPath(-Infinity, 0)", "false");
+ _assertSame(ctx.isPointInPath(NaN, 0), false, "ctx.isPointInPath(NaN, 0)", "false");
+ _assertSame(ctx.isPointInPath(0, Infinity), false, "ctx.isPointInPath(0, Infinity)", "false");
+ _assertSame(ctx.isPointInPath(0, -Infinity), false, "ctx.isPointInPath(0, -Infinity)", "false");
+ _assertSame(ctx.isPointInPath(0, NaN), false, "ctx.isPointInPath(0, NaN)", "false");
+ _assertSame(ctx.isPointInPath(NaN, NaN), false, "ctx.isPointInPath(NaN, NaN)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.outside.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.outside.html
new file mode 100644
index 0000000000..6431879eb6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.outside.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.outside</h1>
+<p class="desc">isPointInPath() works on paths outside the canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() works on paths outside the canvas");
+_addTest(function(canvas, ctx) {
+
+ ctx.rect(0, -100, 20, 20);
+ ctx.rect(20, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(10, -110), false, "ctx.isPointInPath(10, -110)", "false");
+ _assertSame(ctx.isPointInPath(10, -90), true, "ctx.isPointInPath(10, -90)", "true");
+ _assertSame(ctx.isPointInPath(10, -70), false, "ctx.isPointInPath(10, -70)", "false");
+ _assertSame(ctx.isPointInPath(30, -20), false, "ctx.isPointInPath(30, -20)", "false");
+ _assertSame(ctx.isPointInPath(30, 0), true, "ctx.isPointInPath(30, 0)", "true");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.subpath.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.subpath.html
new file mode 100644
index 0000000000..5d664557d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.subpath.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.subpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.subpath</h1>
+<p class="desc">isPointInPath() uses the current path, not just the subpath</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() uses the current path, not just the subpath");
+_addTest(function(canvas, ctx) {
+
+ ctx.rect(0, 0, 20, 20);
+ ctx.beginPath();
+ ctx.rect(20, 0, 20, 20);
+ ctx.closePath();
+ ctx.rect(40, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(30, 10), true, "ctx.isPointInPath(30, 10)", "true");
+ _assertSame(ctx.isPointInPath(50, 10), true, "ctx.isPointInPath(50, 10)", "true");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.1.html
new file mode 100644
index 0000000000..7268c3255f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.transform.1</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.translate(50, 0);
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.2.html
new file mode 100644
index 0000000000..3adac7a419
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.transform.2</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(50, 0);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.3.html
new file mode 100644
index 0000000000..8769c8a593
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.transform.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.transform.3</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.scale(-1, 1);
+ ctx.rect(-70, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.4.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.4.html
new file mode 100644
index 0000000000..1bcc0bc3a3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.transform.4.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.transform.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.transform.4</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.translate(50, 0);
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(0, 50);
+ _assertSame(ctx.isPointInPath(60, 10), false, "ctx.isPointInPath(60, 10)", "false");
+ _assertSame(ctx.isPointInPath(110, 10), true, "ctx.isPointInPath(110, 10)", "true");
+ _assertSame(ctx.isPointInPath(110, 60), false, "ctx.isPointInPath(110, 60)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.unclosed.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.unclosed.html
new file mode 100644
index 0000000000..2e3b711129
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.unclosed.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.unclosed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.unclosed</h1>
+<p class="desc">isPointInPath() works on unclosed subpaths</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() works on unclosed subpaths");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(20, 0);
+ ctx.lineTo(20, 20);
+ ctx.lineTo(0, 20);
+ _assertSame(ctx.isPointInPath(10, 10), true, "ctx.isPointInPath(10, 10)", "true");
+ _assertSame(ctx.isPointInPath(30, 10), false, "ctx.isPointInPath(30, 10)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.winding.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.winding.html
new file mode 100644
index 0000000000..ec22570797
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInPath.winding.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInPath.winding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInPath.winding</h1>
+<p class="desc">isPointInPath() uses the non-zero winding number rule</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInPath() uses the non-zero winding number rule");
+_addTest(function(canvas, ctx) {
+
+ // Create a square ring, using opposite windings to make a hole in the centre
+ ctx.moveTo(0, 0);
+ ctx.lineTo(50, 0);
+ ctx.lineTo(50, 50);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.lineTo(10, 40);
+ ctx.lineTo(40, 40);
+ ctx.lineTo(40, 10);
+ ctx.lineTo(10, 10);
+
+ _assertSame(ctx.isPointInPath(5, 5), true, "ctx.isPointInPath(5, 5)", "true");
+ _assertSame(ctx.isPointInPath(25, 5), true, "ctx.isPointInPath(25, 5)", "true");
+ _assertSame(ctx.isPointInPath(45, 5), true, "ctx.isPointInPath(45, 5)", "true");
+ _assertSame(ctx.isPointInPath(5, 25), true, "ctx.isPointInPath(5, 25)", "true");
+ _assertSame(ctx.isPointInPath(25, 25), false, "ctx.isPointInPath(25, 25)", "false");
+ _assertSame(ctx.isPointInPath(45, 25), true, "ctx.isPointInPath(45, 25)", "true");
+ _assertSame(ctx.isPointInPath(5, 45), true, "ctx.isPointInPath(5, 45)", "true");
+ _assertSame(ctx.isPointInPath(25, 45), true, "ctx.isPointInPath(25, 45)", "true");
+ _assertSame(ctx.isPointInPath(45, 45), true, "ctx.isPointInPath(45, 45)", "true");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInStroke.scaleddashes.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInStroke.scaleddashes.html
new file mode 100644
index 0000000000..e27baa1549
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInStroke.scaleddashes.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInStroke.scaleddashes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInStroke.scaleddashes</h1>
+<p class="desc">isPointInStroke() should return correct results on dashed paths at high scale factors</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("isPointInStroke() should return correct results on dashed paths at high scale factors");
+_addTest(function(canvas, ctx) {
+
+ var scale = 20;
+ ctx.setLineDash([10, 21.4159]); // dash from t=0 to t=10 along the circle
+ ctx.scale(scale, scale);
+ ctx.ellipse(6, 10, 5, 5, 0, 2*Math.PI, false);
+ ctx.stroke();
+
+ // hit-test the beginning of the dash (t=0)
+ _assertSame(ctx.isPointInStroke(11*scale, 10*scale), true, "ctx.isPointInStroke(11*scale, 10*scale)", "true");
+ // hit-test the middle of the dash (t=5)
+ _assertSame(ctx.isPointInStroke(8.70*scale, 14.21*scale), true, "ctx.isPointInStroke(8.70*scale, 14.21*scale)", "true");
+ // hit-test the end of the dash (t=9.8)
+ _assertSame(ctx.isPointInStroke(4.10*scale, 14.63*scale), true, "ctx.isPointInStroke(4.10*scale, 14.63*scale)", "true");
+ // hit-test past the end of the dash (t=10.2)
+ _assertSame(ctx.isPointInStroke(3.74*scale, 14.46*scale), false, "ctx.isPointInStroke(3.74*scale, 14.46*scale)", "false");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.invalid.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.invalid.html
new file mode 100644
index 0000000000..301c7c447d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.invalid.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInpath.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInpath.invalid</h1>
+<p class="desc">Verify isPointInPath throws exceptions with invalid inputs.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify isPointInPath throws exceptions with invalid inputs.");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 200;
+ canvas.height = 200;
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ // Testing invalid enumeration isPointInPath (w/ and w/o Path object');
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(path, 50, 50, 'gazonk'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(50, 50, 'gazonk'); });
+
+ // Testing invalid type isPointInPath with Path object');
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, null); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(path, 50, 50, null); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, undefined); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50, 'evenodd'); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.multi.path.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.multi.path.html
new file mode 100644
index 0000000000..d71bd8a4c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.isPointInpath.multi.path.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.isPointInpath.multi.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.isPointInpath.multi.path</h1>
+<p class="desc">Verify the winding rule in isPointInPath works for path object.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify the winding rule in isPointInPath works for path object.");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(path, 50, 50), true, "ctx.isPointInPath(path, 50, 50)", "true");
+ _assertSame(ctx.isPointInPath(path, 50, 50, undefined), true, "ctx.isPointInPath(path, 50, 50, undefined)", "true");
+ _assertSame(ctx.isPointInPath(path, NaN, 50), false, "ctx.isPointInPath(path, NaN, 50)", "false");
+ _assertSame(ctx.isPointInPath(path, 50, NaN), false, "ctx.isPointInPath(path, 50, NaN)", "false");
+
+ // Testing nonzero isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(path, 50, 50, 'nonzero'), true, "ctx.isPointInPath(path, 50, 50, 'nonzero')", "true");
+
+ // Testing evenodd isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ assert_false(ctx.isPointInPath(path, 50, 50, 'evenodd'));
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.basic.html
new file mode 100644
index 0000000000..c6f2caa196
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.basic.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.lineTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.lineTo.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..ada8f0ca29
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.lineTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.lineTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the point is added and nothing is drawn</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the point is added and nothing is drawn");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..ac1f9238ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.ensuresubpath.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.lineTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.lineTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the point is added and used for subsequent drawing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the point is added and used for subsequent drawing");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nextpoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nextpoint.html
new file mode 100644
index 0000000000..f403c6b508
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nextpoint.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.lineTo.nextpoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.lineTo.nextpoint</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.details.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.details.html
new file mode 100644
index 0000000000..d7595db7d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.details.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.lineTo.nonfinite.details</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.lineTo.nonfinite.details</h1>
+<p class="desc">lineTo() with Infinity/NaN for first arg still converts the second arg</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/clear-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineTo() with Infinity/NaN for first arg still converts the second arg");
+_addTest(function(canvas, ctx) {
+
+ for (var arg1 of [Infinity, -Infinity, NaN]) {
+ var converted = false;
+ ctx.lineTo(arg1, { valueOf: function() { converted = true; return 0; } });
+ _assert(converted, "converted");
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.html
new file mode 100644
index 0000000000..8246064ea3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.lineTo.nonfinite.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.lineTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.lineTo.nonfinite</h1>
+<p class="desc">lineTo() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("lineTo() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(Infinity, 50);
+ ctx.lineTo(-Infinity, 50);
+ ctx.lineTo(NaN, 50);
+ ctx.lineTo(0, Infinity);
+ ctx.lineTo(0, -Infinity);
+ ctx.lineTo(0, NaN);
+ ctx.lineTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.basic.html
new file mode 100644
index 0000000000..d08d67621e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.basic.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.moveTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.moveTo.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 10, 50);
+ ctx.moveTo(100, 0);
+ ctx.lineTo(10, 0);
+ ctx.lineTo(10, 50);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 90,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.multiple.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.multiple.html
new file mode 100644
index 0000000000..384d9fb437
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.multiple.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.moveTo.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.moveTo.multiple</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 25);
+ ctx.moveTo(100, 25);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.newsubpath.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.newsubpath.html
new file mode 100644
index 0000000000..2a3d69b637
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.newsubpath.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.moveTo.newsubpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.moveTo.newsubpath</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.moveTo(100, 0);
+ ctx.moveTo(100, 50);
+ ctx.moveTo(0, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.nonfinite.html
new file mode 100644
index 0000000000..c6cd6f8178
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.moveTo.nonfinite.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.moveTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.moveTo.nonfinite</h1>
+<p class="desc">moveTo() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("moveTo() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.moveTo(Infinity, 50);
+ ctx.moveTo(-Infinity, 50);
+ ctx.moveTo(NaN, 50);
+ ctx.moveTo(0, Infinity);
+ ctx.moveTo(0, -Infinity);
+ ctx.moveTo(0, NaN);
+ ctx.moveTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.basic.html
new file mode 100644
index 0000000000..ffbf039440
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.basic.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.quadraticCurveTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.quadraticCurveTo.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.quadraticCurveTo(100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..f8b8b515ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.quadraticCurveTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.quadraticCurveTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the first control point is added (and nothing is drawn up to it)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(100, 50, 200, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 95,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..189c744c65
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.quadraticCurveTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.quadraticCurveTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the first control point is added</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("If there is no subpath, the first control point is added");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(0, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.nonfinite.html
new file mode 100644
index 0000000000..1488e78a00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.nonfinite.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.quadraticCurveTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.quadraticCurveTo.nonfinite</h1>
+<p class="desc">quadraticCurveTo() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("quadraticCurveTo() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.quadraticCurveTo(Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(-Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(NaN, 50, 0, 50);
+ ctx.quadraticCurveTo(0, Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, -Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, NaN, 0, 50);
+ ctx.quadraticCurveTo(0, 50, Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, -Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, NaN, 50);
+ ctx.quadraticCurveTo(0, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, -Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, NaN);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.scaled.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.scaled.html
new file mode 100644
index 0000000000..90973a8f97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.scaled.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.quadraticCurveTo.scaled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.quadraticCurveTo.scaled</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-1, 1.05);
+ ctx.quadraticCurveTo(0, -1, 1.2, 1.05);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.shape.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.shape.html
new file mode 100644
index 0000000000..23725c2421
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.quadraticCurveTo.shape.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.quadraticCurveTo.shape</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.quadraticCurveTo.shape</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-1000, 1050);
+ ctx.quadraticCurveTo(0, -1000, 1200, 1050);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.basic.html
new file mode 100644
index 0000000000..716cd29af7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.basic.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.closed.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.closed.html
new file mode 100644
index 0000000000..385a88ab7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.closed.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.closed</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.rect(100, 50, 100, 100);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.1.html
new file mode 100644
index 0000000000..e1fd8052d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.end.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.end.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.rect(200, 100, 400, 1000);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.2.html
new file mode 100644
index 0000000000..d30bb111f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.end.2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.end.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.end.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.rect(150, 150, 2000, 2000);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.negative.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.negative.html
new file mode 100644
index 0000000000..b917137bae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.negative.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.negative</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 50, 25);
+ ctx.rect(100, 0, -50, 25);
+ ctx.rect(0, 50, 50, -25);
+ ctx.rect(100, 50, -50, -25);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.newsubpath.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.newsubpath.html
new file mode 100644
index 0000000000..32b70ff2d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.newsubpath.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.newsubpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.newsubpath</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.rect(200, 25, 1, 1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.nonfinite.html
new file mode 100644
index 0000000000..c0d245a49c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.nonfinite.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.nonfinite</h1>
+<p class="desc">rect() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("rect() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.rect(Infinity, 50, 1, 1);
+ ctx.rect(-Infinity, 50, 1, 1);
+ ctx.rect(NaN, 50, 1, 1);
+ ctx.rect(0, Infinity, 1, 1);
+ ctx.rect(0, -Infinity, 1, 1);
+ ctx.rect(0, NaN, 1, 1);
+ ctx.rect(0, 50, Infinity, 1);
+ ctx.rect(0, 50, -Infinity, 1);
+ ctx.rect(0, 50, NaN, 1);
+ ctx.rect(0, 50, 1, Infinity);
+ ctx.rect(0, 50, 1, -Infinity);
+ ctx.rect(0, 50, 1, NaN);
+ ctx.rect(Infinity, Infinity, 1, 1);
+ ctx.rect(Infinity, Infinity, Infinity, 1);
+ ctx.rect(Infinity, Infinity, Infinity, Infinity);
+ ctx.rect(Infinity, Infinity, 1, Infinity);
+ ctx.rect(Infinity, 50, Infinity, 1);
+ ctx.rect(Infinity, 50, Infinity, Infinity);
+ ctx.rect(Infinity, 50, 1, Infinity);
+ ctx.rect(0, Infinity, Infinity, 1);
+ ctx.rect(0, Infinity, Infinity, Infinity);
+ ctx.rect(0, Infinity, 1, Infinity);
+ ctx.rect(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.selfintersect.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.selfintersect.html
new file mode 100644
index 0000000000..8ebbf0c1f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.selfintersect.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.selfintersect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.selfintersect</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.rect(45, 20, 10, 10);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.winding.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.winding.html
new file mode 100644
index 0000000000..d7350ef38c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.winding.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.winding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.winding</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.rect(0, 0, 50, 50);
+ ctx.rect(100, 50, -50, -50);
+ ctx.rect(0, 25, 100, -25);
+ ctx.rect(100, 25, -100, 25);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.1.html
new file mode 100644
index 0000000000..c773ef61d0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.zero.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(0, 50, 100, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.2.html
new file mode 100644
index 0000000000..5888231fc6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.zero.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, -100, 0, 250);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.3.html
new file mode 100644
index 0000000000..c000b008fb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.zero.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.zero.3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.4.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.4.html
new file mode 100644
index 0000000000..bb3ecb3aa5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.4.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.zero.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.zero.4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.rect(100, 25, 0, 0);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.5.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.5.html
new file mode 100644
index 0000000000..081c753d91
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.5.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.zero.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.zero.5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.rect(100, 25, 0, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.6.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.6.html
new file mode 100644
index 0000000000..dafb273d56
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.rect.zero.6.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.rect.zero.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.rect.zero.6</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.rect(100, 25, 1000, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html
new file mode 100644
index 0000000000..3bb890ae96
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.1.radius.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.1.radius.dompoint</h1>
+<p class="desc">Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html
new file mode 100644
index 0000000000..96e933870b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.1.radius.dompoint.single argument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.1.radius.dompoint.single argument</h1>
+<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, new DOMPoint(40, 20));
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html
new file mode 100644
index 0000000000..1315233d79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.1.radius.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.1.radius.dompointinit</h1>
+<p class="desc">Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html
new file mode 100644
index 0000000000..f5c6d00959
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.1.radius.dompointinit.single.argument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.1.radius.dompointinit.single.argument</h1>
+<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, {x: 40, y: 20});
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.html
new file mode 100644
index 0000000000..402631a7a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.1.radius.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.1.radius.double</h1>
+<p class="desc">Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.single.argument.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.single.argument.html
new file mode 100644
index 0000000000..ed4887c2de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.1.radius.double.single.argument.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.1.radius.double.single.argument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.1.radius.double.single.argument</h1>
+<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, 20);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompoint.html
new file mode 100644
index 0000000000..00a9c14582
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompoint.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.2.radii.1.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.2.radii.1.dompoint</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html
new file mode 100644
index 0000000000..e9b3a7bf79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.2.radii.1.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.2.radii.1.dompointinit</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.double.html
new file mode 100644
index 0000000000..a2f02104e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.1.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.2.radii.1.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.2.radii.1.double</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompoint.html
new file mode 100644
index 0000000000..57df30d5ae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompoint.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.2.radii.2.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.2.radii.2.dompoint</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html
new file mode 100644
index 0000000000..5942ab750f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.2.radii.2.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.2.radii.2.dompointinit</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.double.html
new file mode 100644
index 0000000000..2390a61dfd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.2.radii.2.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.2.radii.2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.2.radii.2.double</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompoint.html
new file mode 100644
index 0000000000..f4fa76afac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompoint.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.1.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.1.dompoint</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html
new file mode 100644
index 0000000000..4e7dc947f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.1.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.1.dompointinit</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.double.html
new file mode 100644
index 0000000000..d7888da6d9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.1.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.1.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.1.double</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompoint.html
new file mode 100644
index 0000000000..38a8baac53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompoint.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.2.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.2.dompoint</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html
new file mode 100644
index 0000000000..5e867caf42
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.2.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.2.dompointinit</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.double.html
new file mode 100644
index 0000000000..41edff205c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.2.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.2.double</h1>
+<p class="desc">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.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("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.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompoint.html
new file mode 100644
index 0000000000..6d6a1a6ae0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompoint.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.3.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.3.dompoint</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html
new file mode 100644
index 0000000000..132420e343
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.3.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.3.dompointinit</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.double.html
new file mode 100644
index 0000000000..75a8e924ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.3.radii.3.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.3.radii.3.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.3.radii.3.double</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompoint.html
new file mode 100644
index 0000000000..b681b59f4e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompoint.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.1.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.1.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html
new file mode 100644
index 0000000000..e5542894b3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.1.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.1.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.double.html
new file mode 100644
index 0000000000..028effa82b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.1.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.1.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.1.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompoint.html
new file mode 100644
index 0000000000..d3c16eb493
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompoint.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.2.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.2.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html
new file mode 100644
index 0000000000..ab5ad3f4da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.2.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.2.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.double.html
new file mode 100644
index 0000000000..ec229e396a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.2.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.2.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompoint.html
new file mode 100644
index 0000000000..5367543fa3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompoint.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.3.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.3.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html
new file mode 100644
index 0000000000..89df524d53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.3.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.3.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.double.html
new file mode 100644
index 0000000000..22ba747b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.3.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.3.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.3.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompoint.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompoint.html
new file mode 100644
index 0000000000..b15c291884
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompoint.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.4.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.4.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html
new file mode 100644
index 0000000000..d9b03a1225
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.4.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.4.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.double.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.double.html
new file mode 100644
index 0000000000..62ccf85958
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.4.radii.4.double.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.4.radii.4.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.4.radii.4.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.badinput.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.badinput.html
new file mode 100644
index 0000000000..39e1d0c655
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.badinput.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.badinput</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.badinput</h1>
+<p class="desc">roundRect() throws or does not throw errors given the strange inputs.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("roundRect() throws or does not throw errors given the strange inputs.");
+_addTest(function(canvas, ctx) {
+
+ ctx.roundRect(0, 0, 100, 100, { foo: "bar" }); //=> DOMPointInit
+ ctx.roundRect(0, 0, 100, 100, undefined); //=> "missing" -> 0
+ ctx.roundRect(0, 0, 100, 100, [[]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [[25]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [undefined]); //=> « DOMPointInit »
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, 0n); });
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, { x: 0n }); });
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, [{ x: 0n }]); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.closed.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.closed.html
new file mode 100644
index 0000000000..89aeb3b865
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.closed.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.closed</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.roundRect(100, 50, 100, 100, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.1.html
new file mode 100644
index 0000000000..be98ce5841
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.end.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.end.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(200, 100, 400, 1000, [0]);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.2.html
new file mode 100644
index 0000000000..16131ad345
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.end.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.end.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.roundRect(150, 150, 2000, 2000, [0]);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.3.html
new file mode 100644
index 0000000000..f9454080eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.3.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.end.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.end.3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(101, 51, 2000, 2000, [500, 500, 500, 500]);
+ ctx.lineTo(-1, -1);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.4.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.4.html
new file mode 100644
index 0000000000..52d49c32e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.end.4.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.end.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.end.4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.roundRect(-1, -1, 2000, 2000, [1000, 1000, 1000, 1000]);
+ ctx.lineTo(-150, -150);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.negative.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.negative.html
new file mode 100644
index 0000000000..66e1172432
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.negative.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.negative</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.roundRect(0, 0, 50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 0, -50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(0, 50, 50, -25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 50, -50, -25, [10, 0, 0, 0]);
+ ctx.fill();
+ // All rects drawn
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ // Correct corners are rounded.
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.newsubpath.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.newsubpath.html
new file mode 100644
index 0000000000..df3990a376
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.newsubpath.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.newsubpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.newsubpath</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.roundRect(200, 25, 1, 1, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.nonfinite.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.nonfinite.html
new file mode 100644
index 0000000000..5f0f0b6eaf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.nonfinite.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.nonfinite</h1>
+<p class="desc">roundRect() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("roundRect() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.roundRect(Infinity, 50, 1, 1, [0]);
+ ctx.roundRect(-Infinity, 50, 1, 1, [0]);
+ ctx.roundRect(NaN, 50, 1, 1, [0]);
+ ctx.roundRect(0, Infinity, 1, 1, [0]);
+ ctx.roundRect(0, -Infinity, 1, 1, [0]);
+ ctx.roundRect(0, NaN, 1, 1, [0]);
+ ctx.roundRect(0, 50, Infinity, 1, [0]);
+ ctx.roundRect(0, 50, -Infinity, 1, [0]);
+ ctx.roundRect(0, 50, NaN, 1, [0]);
+ ctx.roundRect(0, 50, 1, Infinity, [0]);
+ ctx.roundRect(0, 50, 1, -Infinity, [0]);
+ ctx.roundRect(0, 50, 1, NaN, [0]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,NaN]);
+ ctx.roundRect(Infinity, Infinity, 1, 1, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, 1, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, Infinity, 1, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, 1, Infinity, [0]);
+ ctx.roundRect(Infinity, Infinity, 1, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, 1, 1, [Infinity]);
+ ctx.roundRect(Infinity, 50, Infinity, 1, [0]);
+ ctx.roundRect(Infinity, 50, Infinity, Infinity, [0]);
+ ctx.roundRect(Infinity, 50, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, 50, Infinity, 1, [Infinity]);
+ ctx.roundRect(Infinity, 50, 1, Infinity, [0]);
+ ctx.roundRect(Infinity, 50, 1, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, 50, 1, 1, [Infinity]);
+ ctx.roundRect(0, Infinity, Infinity, 1, [0]);
+ ctx.roundRect(0, Infinity, Infinity, Infinity, [0]);
+ ctx.roundRect(0, Infinity, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(0, Infinity, Infinity, 1, [Infinity]);
+ ctx.roundRect(0, Infinity, 1, Infinity, [0]);
+ ctx.roundRect(0, Infinity, 1, Infinity, [Infinity]);
+ ctx.roundRect(0, Infinity, 1, 1, [Infinity]);
+ ctx.roundRect(0, 50, Infinity, Infinity, [0]);
+ ctx.roundRect(0, 50, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(0, 50, Infinity, 1, [Infinity]);
+ ctx.roundRect(0, 50, 1, Infinity, [Infinity]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, -Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, NaN)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(-Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(NaN, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: -Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: NaN}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: -Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: NaN, y: 10}]);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.1.html
new file mode 100644
index 0000000000..913b17e45e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.1.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.intersecting.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.intersecting.1</h1>
+<p class="desc">Check that roundRects with intersecting corner arcs are rendered correctly.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that roundRects with intersecting corner arcs are rendered correctly.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [40, 40, 40, 40]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 2,25, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 97,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.2.html
new file mode 100644
index 0000000000..abd7f86088
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.intersecting.2.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.intersecting.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.intersecting.2</h1>
+<p class="desc">Check that roundRects with intersecting corner arcs are rendered correctly.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that roundRects with intersecting corner arcs are rendered correctly.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [1000, 1000, 1000, 1000]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 2,25, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 97,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html
new file mode 100644
index 0000000000..ac2532dcfe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.negative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.negative</h1>
+<p class="desc">roundRect() with negative radius throws an exception</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("roundRect() with negative radius throws an exception");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(-1, 1), 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(1, -1)])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: -1, y: 1}, 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: 1, y: -1}])});
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noargument.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noargument.html
new file mode 100644
index 0000000000..cfaf87ecf2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noargument.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.noargument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.noargument</h1>
+<p class="desc">Check that roundRect draws a rectangle when no radii are provided.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that roundRect draws a rectangle when no radii are provided.");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(10, 10, 80, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ // upper left corner (10, 10)
+ _assertPixel(canvas, 10,9, 255,0,0,255);
+ _assertPixel(canvas, 9,10, 255,0,0,255);
+ _assertPixel(canvas, 10,10, 0,255,0,255);
+
+ // upper right corner (89, 10)
+ _assertPixel(canvas, 90,10, 255,0,0,255);
+ _assertPixel(canvas, 89,9, 255,0,0,255);
+ _assertPixel(canvas, 89,10, 0,255,0,255);
+
+ // lower right corner (89, 39)
+ _assertPixel(canvas, 89,40, 255,0,0,255);
+ _assertPixel(canvas, 90,39, 255,0,0,255);
+ _assertPixel(canvas, 89,39, 0,255,0,255);
+
+ // lower left corner (10, 30)
+ _assertPixel(canvas, 9,39, 255,0,0,255);
+ _assertPixel(canvas, 10,40, 255,0,0,255);
+ _assertPixel(canvas, 10,39, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noarugment.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noarugment.html
new file mode 100644
index 0000000000..08f576b379
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.noarugment.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.noarugment</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.noarugment</h1>
+<p class="desc">Check that roundRect draws a rectangle when no radii are provided.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that roundRect draws a rectangle when no radii are provided.");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+ctx.roundRect(10, 10, 80, 30);
+ctx.fillStyle = '#0f0';
+ctx.fill();
+// upper left corner (10, 10)
+_assertPixel(canvas, 10,9, 255,0,0,255);
+_assertPixel(canvas, 9,10, 255,0,0,255);
+_assertPixel(canvas, 10,10, 0,255,0,255);
+
+// upper right corner (89, 10)
+_assertPixel(canvas, 90,10, 255,0,0,255);
+_assertPixel(canvas, 89,9, 255,0,0,255);
+_assertPixel(canvas, 89,10, 0,255,0,255);
+
+// lower right corner (89, 39)
+_assertPixel(canvas, 89,40, 255,0,0,255);
+_assertPixel(canvas, 90,39, 255,0,0,255);
+_assertPixel(canvas, 89,39, 0,255,0,255);
+
+// lower left corner (10, 30)
+_assertPixel(canvas, 9,39, 255,0,0,255);
+_assertPixel(canvas, 10,40, 255,0,0,255);
+_assertPixel(canvas, 10,39, 0,255,0,255);
+
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html
new file mode 100644
index 0000000000..8363285ffc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.none.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.none</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.none</h1>
+<p class="desc">Check that roundRect throws an RangeError if radii is an empty array.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that roundRect throws an RangeError if radii is an empty array.");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])});
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html
new file mode 100644
index 0000000000..d8fe4bb45c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.radius.toomany.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.toomany</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.toomany</h1>
+<p class="desc">Check that roundRect throws an IndeSizeError if radii has more than four items.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that roundRect throws an IndeSizeError if radii has more than four items.");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])});
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.selfintersect.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.selfintersect.html
new file mode 100644
index 0000000000..7a69aaf4c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.selfintersect.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.selfintersect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.selfintersect</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 100, 50, [0]);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.roundRect(45, 20, 10, 10, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.winding.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.winding.html
new file mode 100644
index 0000000000..9c1f985eb9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.winding.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.winding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.winding</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 50, 50, [0]);
+ ctx.roundRect(100, 50, -50, -50, [0]);
+ ctx.roundRect(0, 25, 100, -25, [0]);
+ ctx.roundRect(100, 25, -100, 25, [0]);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.1.html
new file mode 100644
index 0000000000..4e9a804dc2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.zero.1</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(0, 50, 100, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.2.html
new file mode 100644
index 0000000000..ac64fa7818
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.zero.2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, -100, 0, 250, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.3.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.3.html
new file mode 100644
index 0000000000..a807715b35
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.3.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.zero.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.zero.3</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, 25, 0, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.4.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.4.html
new file mode 100644
index 0000000000..fc51918c27
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.4.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.zero.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.zero.4</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.5.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.5.html
new file mode 100644
index 0000000000..de7d41b68f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.5.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.zero.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.zero.5</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.6.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.6.html
new file mode 100644
index 0000000000..1e8e338a73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.roundrect.zero.6.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.zero.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.zero.6</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.roundRect(100, 25, 1000, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.empty.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.empty.html
new file mode 100644
index 0000000000..aa459ec986
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.empty.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.empty</h1>
+<p class="desc">Empty subpaths are not stroked</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Empty subpaths are not stroked");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(40, 25);
+ ctx.moveTo(60, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.html
new file mode 100644
index 0000000000..a577f22769
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.overlap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.overlap</h1>
+<p class="desc">Stroked subpaths are combined before being drawn</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.path.stroke.overlap.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Stroked subpaths are combined before being drawn");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 20);
+ ctx.lineTo(100, 20);
+ ctx.moveTo(0, 30);
+ ctx.lineTo(100, 30);
+ ctx.stroke();
+
+ _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.png b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.png
new file mode 100644
index 0000000000..e2a35d48d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.overlap.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.arc.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.arc.html
new file mode 100644
index 0000000000..6474a15424
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.arc.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.prune.arc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.prune.arc</h1>
+<p class="desc">Zero-length line segments from arcTo and arc are removed before stroking</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Zero-length line segments from arcTo and arc are removed before stroking");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 150, 25, 10);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(60, 25);
+ ctx.arc(50, 25, 10, 0, 0, false);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.closed.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.closed.html
new file mode 100644
index 0000000000..16b46852a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.closed.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.prune.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.prune.closed</h1>
+<p class="desc">Zero-length line segments from closed paths are removed before stroking</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Zero-length line segments from closed paths are removed before stroking");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.corner.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.corner.html
new file mode 100644
index 0000000000..226fccc6d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.corner.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.prune.corner</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.prune.corner</h1>
+<p class="desc">Zero-length line segments are removed before stroking with miters</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Zero-length line segments are removed before stroking with miters");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.4;
+
+ ctx.beginPath();
+ ctx.moveTo(-1000, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 1000);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.curve.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.curve.html
new file mode 100644
index 0000000000..8023b7b3f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.curve.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.prune.curve</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.prune.curve</h1>
+<p class="desc">Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.quadraticCurveTo(50, 25, 50, 25);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.line.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.line.html
new file mode 100644
index 0000000000..97f88847c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.line.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.prune.line</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.prune.line</h1>
+<p class="desc">Zero-length line segments from lineTo are removed before stroking</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Zero-length line segments from lineTo are removed before stroking");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.rect.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.rect.html
new file mode 100644
index 0000000000..bf1fc9aa20
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.prune.rect.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.prune.rect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.prune.rect</h1>
+<p class="desc">Zero-length line segments from rect and strokeRect are removed before stroking</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Zero-length line segments from rect and strokeRect are removed before stroking");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+
+ ctx.strokeRect(50, 25, 0, 0);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale1.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale1.html
new file mode 100644
index 0000000000..3e4651ec4a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale1.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.scale1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.scale1</h1>
+<p class="desc">Stroke line widths are scaled by the current transformation matrix</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Stroke line widths are scaled by the current transformation matrix");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale2.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale2.html
new file mode 100644
index 0000000000..099efec76c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.scale2.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.scale2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.scale2</h1>
+<p class="desc">Stroke line widths are scaled by the current transformation matrix</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Stroke line widths are scaled by the current transformation matrix");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.skew.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.skew.html
new file mode 100644
index 0000000000..86f3eebf1d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.skew.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.skew</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.skew</h1>
+<p class="desc">Strokes lines are skewed by the current transformation matrix</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Strokes lines are skewed by the current transformation matrix");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(49, -50);
+ ctx.lineTo(201, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 283);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.unaffected.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.unaffected.html
new file mode 100644
index 0000000000..8e6b41946f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.unaffected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.unaffected</h1>
+<p class="desc">Stroking does not start a new path or subpath</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Stroking does not start a new path or subpath");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+
+ ctx.closePath();
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.union.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.union.html
new file mode 100644
index 0000000000..73198ab24d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.stroke.union.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.stroke.union</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.stroke.union</h1>
+<p class="desc">Strokes in opposite directions are unioned, not subtracted</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Strokes in opposite directions are unioned, not subtracted");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 40;
+ ctx.moveTo(0, 10);
+ ctx.lineTo(100, 10);
+ ctx.moveTo(100, 40);
+ ctx.lineTo(0, 40);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.basic.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.basic.html
new file mode 100644
index 0000000000..1cdc81e4f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.basic.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.transformation.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.transformation.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-100, 0);
+ ctx.rect(100, 0, 100, 50);
+ ctx.translate(0, -100);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.changing.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.changing.html
new file mode 100644
index 0000000000..8f711b6b9a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.changing.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.transformation.changing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.transformation.changing</h1>
+<p class="desc">Transformations are applied while building paths, not when drawing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Transformations are applied while building paths, not when drawing");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.translate(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.translate(-100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(1000, 1000);
+ ctx.rotate(Math.PI/2);
+ ctx.scale(0.1, 0.1);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.multiple.html b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.multiple.html
new file mode 100644
index 0000000000..af06c06371
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/path-objects/2d.path.transformation.multiple.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.transformation.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.transformation.multiple</h1>
+<p class="desc">Transformations are applied while building paths, not when drawing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Transformations are applied while building paths, not when drawing");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.translate(-100, 0);
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ ctx.translate(100, 0);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.translate(0, -50);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ ctx.translate(0, 50);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create.and.resize.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create.and.resize.html
new file mode 100644
index 0000000000..1ecd3fbd65
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create.and.resize.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create.and.resize</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create.and.resize</h1>
+<p class="desc">Verify no crash when resizing an image bitmap to zero.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify no crash when resizing an image bitmap to zero.");
+_addTest(function(canvas, ctx) {
+
+ var image = new Image();
+ image.onload = t.step_func(function() {
+ var options = { resizeHeight: 0 };
+ var p1 = createImageBitmap(image, options);
+ p1.catch(function(error){});
+ t.done();
+ });
+ image.src = 'red.png';
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.basic.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.basic.html
new file mode 100644
index 0000000000..1ea73690e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.basic.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create1.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create1.basic</h1>
+<p class="desc">createImageData(imgdata) exists and returns something</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(imgdata) exists and returns something");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(ctx.createImageData(ctx.createImageData(1, 1)), null, "ctx.createImageData(ctx.createImageData(1, 1))", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.initial.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.initial.html
new file mode 100644
index 0000000000..8709623a0c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.initial.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create1.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create1.initial</h1>
+<p class="desc">createImageData(imgdata) returns transparent black data of the right size</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(imgdata) returns transparent black data of the right size");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata1 = ctx.getImageData(0, 0, 10, 20);
+ var imgdata2 = ctx.createImageData(imgdata1);
+ _assertSame(imgdata2.data.length, imgdata1.data.length, "imgdata2.data.length", "imgdata1.data.length");
+ _assertSame(imgdata2.width, imgdata1.width, "imgdata2.width", "imgdata1.width");
+ _assertSame(imgdata2.height, imgdata1.height, "imgdata2.height", "imgdata1.height");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata2.data.length; ++i)
+ if (imgdata2.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.this.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.this.html
new file mode 100644
index 0000000000..dd4b80ec08
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.this.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create1.this</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create1.this</h1>
+<p class="desc">createImageData(imgdata) should throw when called with the wrong |this|</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(imgdata) should throw when called with the wrong |this|");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.createImageData(1, 1);
+ assert_throws_js(TypeError, function() { CanvasRenderingContext2D.prototype.createImageData.call(null, imgdata); });
+ assert_throws_js(TypeError, function() { CanvasRenderingContext2D.prototype.createImageData.call(undefined, imgdata); });
+ assert_throws_js(TypeError, function() { CanvasRenderingContext2D.prototype.createImageData.call({}, imgdata); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.type.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.type.html
new file mode 100644
index 0000000000..36f3db99be
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.type.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create1.type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create1.type</h1>
+<p class="desc">createImageData(imgdata) returns an ImageData object containing a Uint8ClampedArray object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(imgdata) returns an ImageData object containing a Uint8ClampedArray object");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
+ _assertDifferent(window.Uint8ClampedArray, undefined, "window.Uint8ClampedArray", "undefined");
+ window.ImageData.prototype.thisImplementsImageData = true;
+ window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
+ var imgdata = ctx.createImageData(ctx.createImageData(1, 1));
+ _assert(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
+ _assert(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.zero.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.zero.html
new file mode 100644
index 0000000000..02619376a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create1.zero.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create1.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create1.zero</h1>
+<p class="desc">createImageData(null) throws TypeError</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(null) throws TypeError");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createImageData(null); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.basic.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.basic.html
new file mode 100644
index 0000000000..807b6dbfa2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.basic.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.basic</h1>
+<p class="desc">createImageData(sw, sh) exists and returns something</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(sw, sh) exists and returns something");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(ctx.createImageData(1, 1), null, "ctx.createImageData(1, 1)", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.double.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.double.html
new file mode 100644
index 0000000000..31aa42d5a8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.double.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.double</h1>
+<p class="desc">createImageData(w, h) double is converted to long</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(w, h) double is converted to long");
+_addTest(function(canvas, ctx) {
+
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.createImageData(-10.01, -10.99);
+ _assertSame(imgdata1.width, 10, "imgdata1.width", "10");
+ _assertSame(imgdata1.height, 10, "imgdata1.height", "10");
+ _assertSame(imgdata2.width, 10, "imgdata2.width", "10");
+ _assertSame(imgdata2.height, 10, "imgdata2.height", "10");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.initial.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.initial.html
new file mode 100644
index 0000000000..c2a69b4c06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.initial.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.initial</h1>
+<p class="desc">createImageData(sw, sh) returns transparent black data of the right size</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(sw, sh) returns transparent black data of the right size");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.createImageData(10, 20);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ _assert(imgdata.width < imgdata.height, "imgdata.width < imgdata.height");
+ _assert(imgdata.width > 0, "imgdata.width > 0");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; ++i)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.large.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.large.html
new file mode 100644
index 0000000000..73b2a1c19f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.large.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.large</h1>
+<p class="desc">createImageData(sw, sh) works for sizes much larger than the canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(sw, sh) works for sizes much larger than the canvas");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.createImageData(1000, 2000);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ _assert(imgdata.width < imgdata.height, "imgdata.width < imgdata.height");
+ _assert(imgdata.width > 0, "imgdata.width > 0");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; i += 7813) // check ~1024 points (assuming normal scaling)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.negative.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.negative.html
new file mode 100644
index 0000000000..7c4a3944eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.negative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.negative</h1>
+<p class="desc">createImageData(sw, sh) takes the absolute magnitude of the size arguments</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(sw, sh) takes the absolute magnitude of the size arguments");
+_addTest(function(canvas, ctx) {
+
+ var imgdata1 = ctx.createImageData(10, 20);
+ var imgdata2 = ctx.createImageData(-10, 20);
+ var imgdata3 = ctx.createImageData(10, -20);
+ var imgdata4 = ctx.createImageData(-10, -20);
+ _assertSame(imgdata1.data.length, imgdata2.data.length, "imgdata1.data.length", "imgdata2.data.length");
+ _assertSame(imgdata2.data.length, imgdata3.data.length, "imgdata2.data.length", "imgdata3.data.length");
+ _assertSame(imgdata3.data.length, imgdata4.data.length, "imgdata3.data.length", "imgdata4.data.length");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.nonfinite.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.nonfinite.html
new file mode 100644
index 0000000000..af30dc9124
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.nonfinite.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.nonfinite</h1>
+<p class="desc">createImageData() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData() throws TypeError if arguments are not finite");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.createImageData(Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(-Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(Infinity, Infinity); });
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ assert_throws_js(TypeError, function() { ctx.createImageData(posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(neginfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(nanobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, neginfobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, nanobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(posinfobj, posinfobj); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.round.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.round.html
new file mode 100644
index 0000000000..c62243f418
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.round.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.round</h1>
+<p class="desc">createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)");
+_addTest(function(canvas, ctx) {
+
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
+ _assertSame(imgdata1.width, imgdata2.width, "imgdata1.width", "imgdata2.width");
+ _assertSame(imgdata1.height, imgdata2.height, "imgdata1.height", "imgdata2.height");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.this.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.this.html
new file mode 100644
index 0000000000..f5373d0edd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.this.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.this</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.this</h1>
+<p class="desc">createImageData(sw, sh) should throw when called with the wrong |this|</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(sw, sh) should throw when called with the wrong |this|");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { CanvasRenderingContext2D.prototype.createImageData.call(null, 1, 1); });
+ assert_throws_js(TypeError, function() { CanvasRenderingContext2D.prototype.createImageData.call(undefined, 1, 1); });
+ assert_throws_js(TypeError, function() { CanvasRenderingContext2D.prototype.createImageData.call({}, 1, 1); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.type.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.type.html
new file mode 100644
index 0000000000..d595d33845
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.type.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.type</h1>
+<p class="desc">createImageData(sw, sh) returns an ImageData object containing a Uint8ClampedArray object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(sw, sh) returns an ImageData object containing a Uint8ClampedArray object");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
+ _assertDifferent(window.Uint8ClampedArray, undefined, "window.Uint8ClampedArray", "undefined");
+ window.ImageData.prototype.thisImplementsImageData = true;
+ window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
+ var imgdata = ctx.createImageData(1, 1);
+ _assert(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
+ _assert(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.zero.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.zero.html
new file mode 100644
index 0000000000..cc949162d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.create2.zero.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.create2.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.create2.zero</h1>
+<p class="desc">createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0.99, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0.1); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.basic.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.basic.html
new file mode 100644
index 0000000000..5f8f199540
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.basic.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.basic</h1>
+<p class="desc">getImageData() exists and returns something</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() exists and returns something");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(ctx.getImageData(0, 0, 100, 50), null, "ctx.getImageData(0, 0, 100, 50)", "null");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.clamp.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.clamp.html
new file mode 100644
index 0000000000..0047e910b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.clamp.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.clamp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.clamp</h1>
+<p class="desc">getImageData() clamps colors to the range [0, 255]</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() clamps colors to the range [0, 255]");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgb(-100, -200, -300)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgb(256, 300, 400)';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata1.data[1], 0, "imgdata1.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata1.data[2], 0, "imgdata1.data[\""+(2)+"\"]", "0");
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ _assertSame(imgdata2.data[0], 255, "imgdata2.data[\""+(0)+"\"]", "255");
+ _assertSame(imgdata2.data[1], 255, "imgdata2.data[\""+(1)+"\"]", "255");
+ _assertSame(imgdata2.data[2], 255, "imgdata2.data[\""+(2)+"\"]", "255");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.double.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.double.html
new file mode 100644
index 0000000000..5cea5fcbc2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.double.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.double</h1>
+<p class="desc">createImageData(w, h) double is converted to long</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("createImageData(w, h) double is converted to long");
+_addTest(function(canvas, ctx) {
+
+ var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99);
+ _assertSame(imgdata1.width, 10, "imgdata1.width", "10");
+ _assertSame(imgdata1.height, 10, "imgdata1.height", "10");
+ _assertSame(imgdata2.width, 10, "imgdata2.width", "10");
+ _assertSame(imgdata2.height, 10, "imgdata2.height", "10");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.invalid.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.invalid.html
new file mode 100644
index 0000000000..689e72f69b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.invalid.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.invalid</h1>
+<p class="desc">Verify getImageData() behavior in invalid cases.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify getImageData() behavior in invalid cases.");
+_addTest(function(canvas, ctx) {
+
+ imageData = ctx.getImageData(0,0,2,2);
+ var testValues = [NaN, true, false, "\"garbage\"", "-1",
+ "0", "1", "2", Infinity, -Infinity,
+ -5, -0.5, 0, 0.5, 5,
+ 5.4, 255, 256, null, undefined];
+ var testResults = [0, 1, 0, 0, 0,
+ 0, 1, 2, 255, 0,
+ 0, 0, 0, 0, 5,
+ 5, 255, 255, 0, 0];
+ for (var i = 0; i < testValues.length; i++) {
+ imageData.data[0] = testValues[i];
+ _assert(imageData.data[0] == testResults[i], "imageData.data[\""+(0)+"\"] == testResults[\""+(i)+"\"]");
+ }
+ imageData.data['foo']='garbage';
+ _assert(imageData.data['foo'] == 'garbage', "imageData.data['foo'] == 'garbage'");
+ imageData.data[-1]='garbage';
+ _assert(imageData.data[-1] == undefined, "imageData.data[-1] == undefined");
+ imageData.data[17]='garbage';
+ _assert(imageData.data[17] == undefined, "imageData.data[\""+(17)+"\"] == undefined");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.large.crash.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.large.crash.html
new file mode 100644
index 0000000000..f41eec7b9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.large.crash.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.large.crash</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.large.crash</h1>
+<p class="desc">Test that canvas crash when image data cannot be allocated.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test that canvas crash when image data cannot be allocated.");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 0xffffffff, 2147483647, 10); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.length.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.length.html
new file mode 100644
index 0000000000..41b9832025
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.length.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.length</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.length</h1>
+<p class="desc">getImageData() returns a correctly-sized Uint8ClampedArray</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns a correctly-sized Uint8ClampedArray");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonfinite.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonfinite.html
new file mode 100644
index 0000000000..a80e905cfd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonfinite.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.nonfinite</h1>
+<p class="desc">getImageData() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() throws TypeError if arguments are not finite");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(-Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(NaN, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, -Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, NaN, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, Infinity, Infinity); });
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(neginfobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(nanobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, neginfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, nanobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, neginfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, nanobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, neginfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, nanobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, posinfobj, posinfobj); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonpremul.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonpremul.html
new file mode 100644
index 0000000000..bc833c2198
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.nonpremul.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.nonpremul</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.nonpremul</h1>
+<p class="desc">getImageData() returns non-premultiplied colors</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns non-premultiplied colors");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(10, 10, 10, 10);
+ _assert(imgdata.data[0] > 200, "imgdata.data[\""+(0)+"\"] > 200");
+ _assert(imgdata.data[1] > 200, "imgdata.data[\""+(1)+"\"] > 200");
+ _assert(imgdata.data[2] > 200, "imgdata.data[\""+(2)+"\"] > 200");
+ _assert(imgdata.data[3] > 100, "imgdata.data[\""+(3)+"\"] > 100");
+ _assert(imgdata.data[3] < 200, "imgdata.data[\""+(3)+"\"] < 200");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.alpha.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.alpha.html
new file mode 100644
index 0000000000..e5b57f650e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.alpha.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.order.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.order.alpha</h1>
+<p class="desc">getImageData() returns A in the fourth component</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns A in the fourth component");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assert(imgdata.data[3] < 200, "imgdata.data[\""+(3)+"\"] < 200");
+ _assert(imgdata.data[3] > 100, "imgdata.data[\""+(3)+"\"] > 100");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.cols.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.cols.html
new file mode 100644
index 0000000000..66fd984ebd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.cols.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.order.cols</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.order.cols</h1>
+<p class="desc">getImageData() returns leftmost columns first</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns leftmost columns first");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 2, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[Math.round(imgdata.width/2*4)], 255, "imgdata.data[Math.round(imgdata.width/2*4)]", "255");
+ _assertSame(imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)], 0, "imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)]", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rgb.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rgb.html
new file mode 100644
index 0000000000..4d15ce7927
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rgb.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.order.rgb</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.order.rgb</h1>
+<p class="desc">getImageData() returns R then G then B</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns R then G then B");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#48c';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0x44, "imgdata.data[\""+(0)+"\"]", "0x44");
+ _assertSame(imgdata.data[1], 0x88, "imgdata.data[\""+(1)+"\"]", "0x88");
+ _assertSame(imgdata.data[2], 0xCC, "imgdata.data[\""+(2)+"\"]", "0xCC");
+ _assertSame(imgdata.data[3], 255, "imgdata.data[\""+(3)+"\"]", "255");
+ _assertSame(imgdata.data[4], 0x44, "imgdata.data[\""+(4)+"\"]", "0x44");
+ _assertSame(imgdata.data[5], 0x88, "imgdata.data[\""+(5)+"\"]", "0x88");
+ _assertSame(imgdata.data[6], 0xCC, "imgdata.data[\""+(6)+"\"]", "0xCC");
+ _assertSame(imgdata.data[7], 255, "imgdata.data[\""+(7)+"\"]", "255");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rows.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rows.html
new file mode 100644
index 0000000000..086ce322e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.order.rows.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.order.rows</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.order.rows</h1>
+<p class="desc">getImageData() returns topmost rows first</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns topmost rows first");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 2);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[Math.floor(imgdata.width/2*4)], 0, "imgdata.data[Math.floor(imgdata.width/2*4)]", "0");
+ _assertSame(imgdata.data[(imgdata.height/2)*imgdata.width*4], 255, "imgdata.data[(imgdata.height/2)*imgdata.width*4]", "255");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.range.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.range.html
new file mode 100644
index 0000000000..d921191772
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.range.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.range</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.range</h1>
+<p class="desc">getImageData() returns values in the range [0, 255]</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns values in the range [0, 255]");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ _assertSame(imgdata2.data[0], 255, "imgdata2.data[\""+(0)+"\"]", "255");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.rounding.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.rounding.html
new file mode 100644
index 0000000000..9255be087b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.rounding.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.rounding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.rounding</h1>
+<p class="desc">Test the handling of non-integer source coordinates in getImageData().</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test the handling of non-integer source coordinates in getImageData().");
+_addTest(function(canvas, ctx) {
+
+ function testDimensions(sx, sy, sw, sh, width, height)
+ {
+ imageData = ctx.getImageData(sx, sy, sw, sh);
+ _assert(imageData.width == width, "imageData.width == width");
+ _assert(imageData.height == height, "imageData.height == height");
+ }
+
+ testDimensions(0, 0, 20, 10, 20, 10);
+
+ testDimensions(.1, .2, 20, 10, 20, 10);
+ testDimensions(.9, .8, 20, 10, 20, 10);
+
+ testDimensions(0, 0, 20.9, 10.9, 20, 10);
+ testDimensions(0, 0, 20.1, 10.1, 20, 10);
+
+ testDimensions(-1, -1, 20, 10, 20, 10);
+
+ testDimensions(-1.1, 0, 20, 10, 20, 10);
+ testDimensions(-1.9, 0, 20, 10, 20, 10);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.negative.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.negative.html
new file mode 100644
index 0000000000..0b84b1caca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.negative.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.source.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.source.negative</h1>
+<p class="desc">getImageData() works with negative width and height, and returns top-to-bottom left-to-right</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() works with negative width and height, and returns top-to-bottom left-to-right");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+
+ var imgdata1 = ctx.getImageData(85, 25, -10, -10);
+ _assertSame(imgdata1.data[0], 255, "imgdata1.data[\""+(0)+"\"]", "255");
+ _assertSame(imgdata1.data[1], 255, "imgdata1.data[\""+(1)+"\"]", "255");
+ _assertSame(imgdata1.data[2], 255, "imgdata1.data[\""+(2)+"\"]", "255");
+ _assertSame(imgdata1.data[3], 255, "imgdata1.data[\""+(3)+"\"]", "255");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+0], 0, "imgdata1.data[imgdata1.data.length-4+0]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+1], 0, "imgdata1.data[imgdata1.data.length-4+1]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+2], 0, "imgdata1.data[imgdata1.data.length-4+2]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+3], 255, "imgdata1.data[imgdata1.data.length-4+3]", "255");
+
+ var imgdata2 = ctx.getImageData(0, 0, -1, -1);
+ _assertSame(imgdata2.data[0], 0, "imgdata2.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata2.data[1], 0, "imgdata2.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata2.data[2], 0, "imgdata2.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata2.data[3], 0, "imgdata2.data[\""+(3)+"\"]", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.outside.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.outside.html
new file mode 100644
index 0000000000..fca97f2e6f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.outside.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.source.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.source.outside</h1>
+<p class="desc">getImageData() returns transparent black outside the canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns transparent black outside the canvas");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#08f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var imgdata1 = ctx.getImageData(-10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata1.data[1], 0, "imgdata1.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata1.data[2], 0, "imgdata1.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata1.data[3], 0, "imgdata1.data[\""+(3)+"\"]", "0");
+
+ var imgdata2 = ctx.getImageData(10, -5, 1, 1);
+ _assertSame(imgdata2.data[0], 0, "imgdata2.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata2.data[1], 0, "imgdata2.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata2.data[2], 0, "imgdata2.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata2.data[3], 0, "imgdata2.data[\""+(3)+"\"]", "0");
+
+ var imgdata3 = ctx.getImageData(200, 5, 1, 1);
+ _assertSame(imgdata3.data[0], 0, "imgdata3.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata3.data[1], 0, "imgdata3.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata3.data[2], 0, "imgdata3.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata3.data[3], 0, "imgdata3.data[\""+(3)+"\"]", "0");
+
+ var imgdata4 = ctx.getImageData(10, 60, 1, 1);
+ _assertSame(imgdata4.data[0], 0, "imgdata4.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata4.data[1], 0, "imgdata4.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata4.data[2], 0, "imgdata4.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata4.data[3], 0, "imgdata4.data[\""+(3)+"\"]", "0");
+
+ var imgdata5 = ctx.getImageData(100, 10, 1, 1);
+ _assertSame(imgdata5.data[0], 0, "imgdata5.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata5.data[1], 0, "imgdata5.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata5.data[2], 0, "imgdata5.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata5.data[3], 0, "imgdata5.data[\""+(3)+"\"]", "0");
+
+ var imgdata6 = ctx.getImageData(0, 10, 1, 1);
+ _assertSame(imgdata6.data[0], 0, "imgdata6.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata6.data[1], 136, "imgdata6.data[\""+(1)+"\"]", "136");
+ _assertSame(imgdata6.data[2], 255, "imgdata6.data[\""+(2)+"\"]", "255");
+ _assertSame(imgdata6.data[3], 255, "imgdata6.data[\""+(3)+"\"]", "255");
+
+ var imgdata7 = ctx.getImageData(-10, 10, 20, 20);
+ _assertSame(imgdata7.data[ 0*4+0], 0, "imgdata7.data[ 0*4+0]", "0");
+ _assertSame(imgdata7.data[ 0*4+1], 0, "imgdata7.data[ 0*4+1]", "0");
+ _assertSame(imgdata7.data[ 0*4+2], 0, "imgdata7.data[ 0*4+2]", "0");
+ _assertSame(imgdata7.data[ 0*4+3], 0, "imgdata7.data[ 0*4+3]", "0");
+ _assertSame(imgdata7.data[ 9*4+0], 0, "imgdata7.data[ 9*4+0]", "0");
+ _assertSame(imgdata7.data[ 9*4+1], 0, "imgdata7.data[ 9*4+1]", "0");
+ _assertSame(imgdata7.data[ 9*4+2], 0, "imgdata7.data[ 9*4+2]", "0");
+ _assertSame(imgdata7.data[ 9*4+3], 0, "imgdata7.data[ 9*4+3]", "0");
+ _assertSame(imgdata7.data[10*4+0], 0, "imgdata7.data[10*4+0]", "0");
+ _assertSame(imgdata7.data[10*4+1], 136, "imgdata7.data[10*4+1]", "136");
+ _assertSame(imgdata7.data[10*4+2], 255, "imgdata7.data[10*4+2]", "255");
+ _assertSame(imgdata7.data[10*4+3], 255, "imgdata7.data[10*4+3]", "255");
+ _assertSame(imgdata7.data[19*4+0], 0, "imgdata7.data[19*4+0]", "0");
+ _assertSame(imgdata7.data[19*4+1], 136, "imgdata7.data[19*4+1]", "136");
+ _assertSame(imgdata7.data[19*4+2], 255, "imgdata7.data[19*4+2]", "255");
+ _assertSame(imgdata7.data[19*4+3], 255, "imgdata7.data[19*4+3]", "255");
+ _assertSame(imgdata7.data[20*4+0], 0, "imgdata7.data[20*4+0]", "0");
+ _assertSame(imgdata7.data[20*4+1], 0, "imgdata7.data[20*4+1]", "0");
+ _assertSame(imgdata7.data[20*4+2], 0, "imgdata7.data[20*4+2]", "0");
+ _assertSame(imgdata7.data[20*4+3], 0, "imgdata7.data[20*4+3]", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.size.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.size.html
new file mode 100644
index 0000000000..800edb8baf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.source.size.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.source.size</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.source.size</h1>
+<p class="desc">getImageData() returns bigger ImageData for bigger source rectangle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns bigger ImageData for bigger source rectangle");
+_addTest(function(canvas, ctx) {
+
+ var imgdata1 = ctx.getImageData(0, 0, 10, 10);
+ var imgdata2 = ctx.getImageData(0, 0, 20, 20);
+ _assert(imgdata2.width > imgdata1.width, "imgdata2.width > imgdata1.width");
+ _assert(imgdata2.height > imgdata1.height, "imgdata2.height > imgdata1.height");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.type.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.type.html
new file mode 100644
index 0000000000..748d46b166
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.type.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.type</h1>
+<p class="desc">getImageData() returns an ImageData object containing a Uint8ClampedArray object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() returns an ImageData object containing a Uint8ClampedArray object");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
+ _assertDifferent(window.Uint8ClampedArray, undefined, "window.Uint8ClampedArray", "undefined");
+ window.ImageData.prototype.thisImplementsImageData = true;
+ window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ _assert(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
+ _assert(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.unaffected.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.unaffected.html
new file mode 100644
index 0000000000..f2f4a2e4fa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.unaffected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.unaffected</h1>
+<p class="desc">getImageData() is not affected by context state</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() is not affected by context state");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50)
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.rect(0, 0, 5, 5);
+ ctx.clip();
+ var imgdata = ctx.getImageData(0, 0, 50, 50);
+ ctx.restore();
+ ctx.putImageData(imgdata, 50, 0);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.zero.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.zero.html
new file mode 100644
index 0000000000..438bc2fb1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.get.zero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.get.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.get.zero</h1>
+<p class="desc">getImageData() throws INDEX_SIZE_ERR if size is zero</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getImageData() throws INDEX_SIZE_ERR if size is zero");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0.1, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0.99); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, -0.1, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, -0.99); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.clamp.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.clamp.html
new file mode 100644
index 0000000000..df8ef1ba20
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.clamp.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.clamp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.clamp</h1>
+<p class="desc">ImageData.data clamps numbers to [0, 255]</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData.data clamps numbers to [0, 255]");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 300;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -100;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 200+Math.pow(2, 32);
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -200-Math.pow(2, 32);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Math.pow(10, 39);
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Math.pow(10, 39);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Infinity;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Infinity;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.bounds.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.bounds.html
new file mode 100644
index 0000000000..01affeb947
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.bounds.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.ctor.array.bounds</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.ctor.array.bounds</h1>
+<p class="desc">ImageData has a usable constructor</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData has a usable constructor");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
+
+ assert_throws_dom("INVALID_STATE_ERR", function() { new ImageData(new Uint8ClampedArray(0), 1); });
+ assert_throws_dom("INVALID_STATE_ERR", function() { new ImageData(new Uint8ClampedArray(3), 1); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(new Uint8ClampedArray(4), 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(new Uint8ClampedArray(4), 1, 2); });
+ assert_throws_js(TypeError, function() { new ImageData(new Uint8Array(8), 1, 2); });
+ assert_throws_js(TypeError, function() { new ImageData(new Int8Array(8), 1, 2); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.html
new file mode 100644
index 0000000000..0cdc025764
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.array.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.ctor.array</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.ctor.array</h1>
+<p class="desc">ImageData has a usable constructor</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData has a usable constructor");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
+
+ var array = new Uint8ClampedArray(8);
+ var imgdata = new window.ImageData(array, 1, 2);
+ _assertSame(imgdata.width, 1, "imgdata.width", "1");
+ _assertSame(imgdata.height, 2, "imgdata.height", "2");
+ _assertSame(imgdata.data, array, "imgdata.data", "array");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.basics.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.basics.html
new file mode 100644
index 0000000000..f7811e7441
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.basics.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.ctor.basics</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.ctor.basics</h1>
+<p class="desc">Testing different type of ImageData constructor</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing different type of ImageData constructor");
+_addTest(function(canvas, ctx) {
+
+ function setRGBA(imageData, i, rgba)
+ {
+ var s = i * 4;
+ imageData[s] = rgba[0];
+ imageData[s + 1] = rgba[1];
+ imageData[s + 2] = rgba[2];
+ imageData[s + 3] = rgba[3];
+ }
+
+ function getRGBA(imageData, i)
+ {
+ var result = [];
+ var s = i * 4;
+ for (var j = 0; j < 4; j++) {
+ result[j] = imageData[s + j];
+ }
+ return result;
+ }
+
+ function assertArrayEquals(actual, expected)
+ {
+ _assertSame(typeof actual, "object", "typeof actual", "\"object\"");
+ _assertDifferent(actual, null, "actual", "null");
+ _assertSame("length" in actual, true, "\"length\" in actual", "true");
+ _assertSame(actual.length, expected.length, "actual.length", "expected.length");
+ for (var i = 0; i < actual.length; i++) {
+ _assertSame(actual.hasOwnProperty(i), expected.hasOwnProperty(i), "actual.hasOwnProperty(i)", "expected.hasOwnProperty(i)");
+ _assertSame(actual[i], expected[i], "actual[\""+(i)+"\"]", "expected[\""+(i)+"\"]");
+ }
+ }
+
+ _assertDifferent(ImageData, undefined, "ImageData", "undefined");
+ imageData = new ImageData(100, 50);
+
+ _assertDifferent(imageData, null, "imageData", "null");
+ _assertDifferent(imageData.data, null, "imageData.data", "null");
+ _assertSame(imageData.width, 100, "imageData.width", "100");
+ _assertSame(imageData.height, 50, "imageData.height", "50");
+ assertArrayEquals(getRGBA(imageData.data, 4), [0, 0, 0, 0]);
+
+ var testColor = [0, 255, 255, 128];
+ setRGBA(imageData.data, 4, testColor);
+ assertArrayEquals(getRGBA(imageData.data, 4), testColor);
+
+ assert_throws_js(TypeError, function() { ImageData(1, 1); });
+ assert_throws_js(TypeError, function() { new ImageData(10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(0, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(10, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData('width', 'height'); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(1 << 31, 1 << 31); });
+ assert_throws_js(TypeError, function() { new ImageData(new Uint8ClampedArray(0)); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(new Uint8Array(100), 25); });
+ assert_throws_dom("INVALID_STATE_ERR", function() { new ImageData(new Uint8ClampedArray(27), 2); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(new Uint8ClampedArray(28), 7, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(new Uint8ClampedArray(104), 14); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(new Uint8ClampedArray([12, 34, 168, 65328]), 1, 151); });
+ assert_throws_js(TypeError, function() { new ImageData(self, 4, 4); });
+ assert_throws_js(TypeError, function() { new ImageData(null, 4, 4); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(imageData.data, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(imageData.data, 13); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(imageData.data, 1 << 31); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(imageData.data, 'biggish'); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(imageData.data, 1 << 24, 1 << 31); });
+ _assertSame(new ImageData(new Uint8ClampedArray(28), 7).height, 1, "new ImageData(new Uint8ClampedArray(28), 7).height", "1");
+
+ imageDataFromData = new ImageData(imageData.data, 100);
+ _assertSame(imageDataFromData.width, 100, "imageDataFromData.width", "100");
+ _assertSame(imageDataFromData.height, 50, "imageDataFromData.height", "50");
+ _assertSame(imageDataFromData.data, imageData.data, "imageDataFromData.data", "imageData.data");
+ assertArrayEquals(getRGBA(imageDataFromData.data, 10), getRGBA(imageData.data, 10));
+ setRGBA(imageData.data, 10, testColor);
+ assertArrayEquals(getRGBA(imageDataFromData.data, 10), getRGBA(imageData.data, 10));
+
+ var data = new Uint8ClampedArray(400);
+ data[22] = 129;
+ imageDataFromData = new ImageData(data, 20, 5);
+ _assertSame(imageDataFromData.width, 20, "imageDataFromData.width", "20");
+ _assertSame(imageDataFromData.height, 5, "imageDataFromData.height", "5");
+ _assertSame(imageDataFromData.data, data, "imageDataFromData.data", "data");
+ assertArrayEquals(getRGBA(imageDataFromData.data, 2), getRGBA(data, 2));
+ setRGBA(imageDataFromData.data, 2, testColor);
+ assertArrayEquals(getRGBA(imageDataFromData.data, 2), getRGBA(data, 2));
+
+ if (window.SharedArrayBuffer) {
+ assert_throws_js(TypeError, function() { new ImageData(new Uint16Array(new SharedArrayBuffer(32)), 4, 2); });
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.bounds.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.bounds.html
new file mode 100644
index 0000000000..5ea899ac86
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.bounds.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.ctor.size.bounds</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.ctor.size.bounds</h1>
+<p class="desc">ImageData has a usable constructor</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData has a usable constructor");
+_addTest(function(canvas, ctx) {
+
+_assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
+assert_throws_dom("INDEX_SIZE_ERR", function() { new window.ImageData(0, 0); });
+assert_throws_dom("INDEX_SIZE_ERR", function() { new window.ImageData(0, 1); });
+assert_throws_dom("INDEX_SIZE_ERR", function() { new window.ImageData(1, 0); });
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.html
new file mode 100644
index 0000000000..a11d8e2340
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.size.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.ctor.size</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.ctor.size</h1>
+<p class="desc">ImageData has a usable constructor</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData has a usable constructor");
+_addTest(function(canvas, ctx) {
+
+ _assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
+
+ var imgdata = new window.ImageData(2, 3);
+ _assertSame(imgdata.width, 2, "imgdata.width", "2");
+ _assertSame(imgdata.height, 3, "imgdata.height", "3");
+ _assertSame(imgdata.data.length, 2 * 3 * 4, "imgdata.data.length", "2 * 3 * 4");
+ for (var i = 0; i < imgdata.data.length; ++i) {
+ _assertSame(imgdata.data[i], 0, "imgdata.data[\""+(i)+"\"]", "0");
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.nan.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.nan.html
new file mode 100644
index 0000000000..974b5898a3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.nan.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.nan</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.nan</h1>
+<p class="desc">ImageData.data converts NaN to 0</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData.data converts NaN to 0");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = NaN;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "cheese";
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.properties.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.properties.html
new file mode 100644
index 0000000000..7eefdb2f55
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.properties.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.properties</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.properties</h1>
+<p class="desc">ImageData objects have the right properties</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData objects have the right properties");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(typeof(imgdata.width), 'number', "typeof(imgdata.width)", "'number'");
+ _assertSame(typeof(imgdata.height), 'number', "typeof(imgdata.height)", "'number'");
+ _assertSame(typeof(imgdata.data), 'object', "typeof(imgdata.data)", "'object'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.readonly.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.readonly.html
new file mode 100644
index 0000000000..f002466bab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.readonly.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.readonly</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.readonly</h1>
+<p class="desc">ImageData objects properties are read-only</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData objects properties are read-only");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ var w = imgdata.width;
+ var h = imgdata.height;
+ var d = imgdata.data;
+ imgdata.width = 123;
+ imgdata.height = 123;
+ imgdata.data = [100,100,100,100];
+ _assertSame(imgdata.width, w, "imgdata.width", "w");
+ _assertSame(imgdata.height, h, "imgdata.height", "h");
+ _assertSame(imgdata.data, d, "imgdata.data", "d");
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[1], 0, "imgdata.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata.data[2], 0, "imgdata.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata.data[3], 0, "imgdata.data[\""+(3)+"\"]", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.round.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.round.html
new file mode 100644
index 0000000000..0f7da4fff5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.round.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.round</h1>
+<p class="desc">ImageData.data rounds numbers with round-to-zero</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData.data rounds numbers with round-to-zero");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 0.499;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 0.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 0.501;
+ _assertSame(imgdata.data[0], 1, "imgdata.data[\""+(0)+"\"]", "1");
+ imgdata.data[0] = 1.499;
+ _assertSame(imgdata.data[0], 1, "imgdata.data[\""+(0)+"\"]", "1");
+ imgdata.data[0] = 1.5;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 1.501;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 2.5;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 3.5;
+ _assertSame(imgdata.data[0], 4, "imgdata.data[\""+(0)+"\"]", "4");
+ imgdata.data[0] = 252.5;
+ _assertSame(imgdata.data[0], 252, "imgdata.data[\""+(0)+"\"]", "252");
+ imgdata.data[0] = 253.5;
+ _assertSame(imgdata.data[0], 254, "imgdata.data[\""+(0)+"\"]", "254");
+ imgdata.data[0] = 254.5;
+ _assertSame(imgdata.data[0], 254, "imgdata.data[\""+(0)+"\"]", "254");
+ imgdata.data[0] = 256.5;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = -0.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = -1.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.set.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.set.html
new file mode 100644
index 0000000000..3d03bd6769
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.set.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.set</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.set</h1>
+<p class="desc">ImageData.data can be modified</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData.data can be modified");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ _assertSame(imgdata.data[0], 100, "imgdata.data[\""+(0)+"\"]", "100");
+ imgdata.data[0] = 200;
+ _assertSame(imgdata.data[0], 200, "imgdata.data[\""+(0)+"\"]", "200");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.string.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.string.html
new file mode 100644
index 0000000000..eda6f2838d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.string.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.string</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.string</h1>
+<p class="desc">ImageData.data converts strings to numbers with ToNumber</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData.data converts strings to numbers with ToNumber");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "110";
+ _assertSame(imgdata.data[0], 110, "imgdata.data[\""+(0)+"\"]", "110");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "0x78";
+ _assertSame(imgdata.data[0], 120, "imgdata.data[\""+(0)+"\"]", "120");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = " +130e0 ";
+ _assertSame(imgdata.data[0], 130, "imgdata.data[\""+(0)+"\"]", "130");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.undefined.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.undefined.html
new file mode 100644
index 0000000000..96867bec4a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.object.undefined.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.object.undefined</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.object.undefined</h1>
+<p class="desc">ImageData.data converts undefined to 0</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("ImageData.data converts undefined to 0");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = undefined;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.html
new file mode 100644
index 0000000000..6ee38802f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.alpha</h1>
+<p class="desc">putImageData() puts non-solid image data correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.imageData.put.alpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() puts non-solid image data correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.25)';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,64, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.png b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.png
new file mode 100644
index 0000000000..5428c65524
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.basic.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.basic.html
new file mode 100644
index 0000000000..17f7d3e8e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.basic.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.basic</h1>
+<p class="desc">putImageData() puts image data from getImageData() onto the canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() puts image data from getImageData() onto the canvas");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html
new file mode 100644
index 0000000000..948f617095
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.clip</h1>
+<p class="desc">putImageData() is not affected by clipping regions</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() is not affected by clipping regions");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.created.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.created.html
new file mode 100644
index 0000000000..4db45873a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.created.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.created</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.created</h1>
+<p class="desc">putImageData() puts image data from createImageData() onto the canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() puts image data from createImageData() onto the canvas");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.createImageData(100, 50);
+ for (var i = 0; i < imgdata.data.length; i += 4) {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ imgdata.data[i+2] = 0;
+ imgdata.data[i+3] = 255;
+ }
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.cross.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.cross.html
new file mode 100644
index 0000000000..10226834a3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.cross.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.cross</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.cross</h1>
+<p class="desc">putImageData() accepts image data got from a different canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() accepts image data got from a different canvas");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50)
+ var imgdata = ctx2.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html
new file mode 100644
index 0000000000..efaa6f2550
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.dirty.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.dirty.negative</h1>
+<p class="desc">putImageData() handles negative-sized dirty rectangles correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() handles negative-sized dirty rectangles correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 20, 20, -20, -20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.outside.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.outside.html
new file mode 100644
index 0000000000..86a77369f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.outside.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.dirty.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.dirty.outside</h1>
+<p class="desc">putImageData() handles dirty rectangles outside the canvas correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() handles dirty rectangles outside the canvas correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+
+ ctx.putImageData(imgdata, 100, 20, 20, 20, -20, -20);
+ ctx.putImageData(imgdata, 200, 200, 0, 0, 100, 50);
+ ctx.putImageData(imgdata, 40, 20, -30, -20, 30, 20);
+ ctx.putImageData(imgdata, -30, 20, 0, 0, 30, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,45, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html
new file mode 100644
index 0000000000..786db5ac4f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.dirty.rect1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.dirty.rect1</h1>
+<p class="desc">putImageData() only modifies areas inside the dirty rectangle, using width and height</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using width and height");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 0, 0, 20, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html
new file mode 100644
index 0000000000..f5f8a3a0d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.dirty.rect2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.dirty.rect2</h1>
+<p class="desc">putImageData() only modifies areas inside the dirty rectangle, using x and y</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using x and y");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(60, 30, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, -20, -10, 60, 30, 20, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.zero.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.zero.html
new file mode 100644
index 0000000000..d3799104dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.zero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.dirty.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.dirty.zero</h1>
+<p class="desc">putImageData() with zero-sized dirty rectangle puts nothing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() with zero-sized dirty rectangle puts nothing");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.modified.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.modified.html
new file mode 100644
index 0000000000..70b70a866f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.modified.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.modified</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.modified</h1>
+<p class="desc">putImageData() puts modified image data correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() puts modified image data correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(45, 20, 10, 10)
+ var imgdata = ctx.getImageData(45, 20, 10, 10);
+ for (var i = 0, len = imgdata.width*imgdata.height*4; i < len; i += 4)
+ {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ }
+ ctx.putImageData(imgdata, 45, 20);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.nonfinite.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.nonfinite.html
new file mode 100644
index 0000000000..ab03f9f20f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.nonfinite.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.nonfinite</h1>
+<p class="desc">putImageData() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() throws TypeError if arguments are not finite");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, -Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, NaN, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, -Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, NaN, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, Infinity); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.null.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.null.html
new file mode 100644
index 0000000000..4ed429fe7c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.null.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.null</h1>
+<p class="desc">putImageData() with null imagedata throws TypeError</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() with null imagedata throws TypeError");
+_addTest(function(canvas, ctx) {
+
+ assert_throws_js(TypeError, function() { ctx.putImageData(null, 0, 0); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.path.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.path.html
new file mode 100644
index 0000000000..e32d7cc257
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.path.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.path</h1>
+<p class="desc">putImageData() does not affect the current path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() does not affect the current path");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.rect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.putImageData(imgdata, 0, 0);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unaffected.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unaffected.html
new file mode 100644
index 0000000000..bad06b745f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unaffected.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.unaffected</h1>
+<p class="desc">putImageData() is not affected by context state</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() is not affected by context state");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.translate(100, 50);
+ ctx.scale(0.1, 0.1);
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html
new file mode 100644
index 0000000000..026e4347ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.unchanged</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.unchanged</h1>
+<p class="desc">putImageData(getImageData(...), ...) has no effect</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData(getImageData(...), ...) has no effect");
+_addTest(function(canvas, ctx) {
+
+ var i = 0;
+ for (var y = 0; y < 16; ++y) {
+ for (var x = 0; x < 16; ++x, ++i) {
+ ctx.fillStyle = 'rgba(' + i + ',' + (Math.floor(i*1.5) % 256) + ',' + (Math.floor(i*23.3) % 256) + ',' + (i/256) + ')';
+ ctx.fillRect(x, y, 1, 1);
+ }
+ }
+ var imgdata1 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ var olddata = [];
+ for (var i = 0; i < imgdata1.data.length; ++i)
+ olddata[i] = imgdata1.data[i];
+
+ ctx.putImageData(imgdata1, 0.1, 0.2);
+
+ var imgdata2 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ for (var i = 0; i < imgdata2.data.length; ++i) {
+ _assertSame(olddata[i], imgdata2.data[i], "olddata[\""+(i)+"\"]", "imgdata2.data[\""+(i)+"\"]");
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.wrongtype.html b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.wrongtype.html
new file mode 100644
index 0000000000..9e43b1fbe9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/pixel-manipulation/2d.imageData.put.wrongtype.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.imageData.put.wrongtype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.imageData.put.wrongtype</h1>
+<p class="desc">putImageData() does not accept non-ImageData objects</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("putImageData() does not accept non-ImageData objects");
+_addTest(function(canvas, ctx) {
+
+ var imgdata = { width: 1, height: 1, data: [255, 0, 0, 255] };
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.putImageData("cheese", 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(42, 0, 0); });
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.basic.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.basic.html
new file mode 100644
index 0000000000..0753ec6da8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.basic.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.basic</h1>
+<p class="desc">reset clears to transparent black</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("reset clears to transparent black");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.reset();
+ _assertPixel(canvas, 0,0, 0,0,0,0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ _assertPixel(canvas, 25,50, 0,0,0,0);
+ _assertPixel(canvas, 100,50, 0,0,0,0);
+ _assertPixel(canvas, 0,50, 0,0,0,0);
+ _assertPixel(canvas, 100,0, 0,0,0,0);
+ t.done();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow-expected.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow-expected.html
new file mode 100644
index 0000000000..182f7e40cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.drop_shadow</title>
+<h1>2d.reset.render.drop_shadow</h1>
+<p class="desc">check that drop shadows are correctly rendered after reset</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(100, 100, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow.html
new file mode 100644
index 0000000000..264355c8b3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.drop_shadow.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.drop_shadow-expected.html">
+<title>Canvas test: 2d.reset.render.drop_shadow</title>
+<h1>2d.reset.render.drop_shadow</h1>
+<p class="desc">check that drop shadows are correctly rendered after reset</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = "red";
+ ctx.shadowBlur = 10;
+
+ ctx.reset();
+
+ ctx.fillRect(100, 100, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation-expected.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation-expected.html
new file mode 100644
index 0000000000..1f9d247634
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.global_composite_operation</title>
+<h1>2d.reset.render.global_composite_operation</h1>
+<p class="desc">check that canvas correctly renders rectangles with the default global composite operation after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(10, 10, 100, 100);
+ ctx.fillRect(50, 50, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation.html
new file mode 100644
index 0000000000..fc851b84b8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.global_composite_operation.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.global_composite_operation-expected.html">
+<title>Canvas test: 2d.reset.render.global_composite_operation</title>
+<h1>2d.reset.render.global_composite_operation</h1>
+<p class="desc">check that canvas correctly renders rectangles with the default global composite operation after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = "xor";
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 100, 100);
+ ctx.fillRect(50, 50, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line-expected.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line-expected.html
new file mode 100644
index 0000000000..dcd648d8c3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line-expected.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.line</title>
+<h1>2d.reset.render.line</h1>
+<p class="desc">check that lines are correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.moveTo(100, 100);
+ ctx.lineTo(100, 300);
+ ctx.lineTo(300, 300);
+ ctx.lineTo(300, 100);
+ ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line.html
new file mode 100644
index 0000000000..0dda7c7a7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.line.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.line-expected.html">
+<title>Canvas test: 2d.reset.render.line</title>
+<h1>2d.reset.render.line</h1>
+<p class="desc">check that lines are correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 10;
+ ctx.lineCap = "round";
+ ctx.lineJoin = "bevel";
+ ctx.lineDashOffset = 10;
+ ctx.setLineDash([20]);
+
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(100, 100);
+ ctx.lineTo(100, 300);
+ ctx.lineTo(300, 300);
+ ctx.lineTo(300, 100);
+ ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc-expected.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc-expected.html
new file mode 100644
index 0000000000..c359e6b42e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.misc</title>
+<h1>2d.reset.render.misc</h1>
+<p class="desc">check that canvas correctly renders rectangles after reset (states not covered by other tests)</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(0, 0, 100, 100);
+ ctx.strokeRect(150, 150, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc.html
new file mode 100644
index 0000000000..61d2dbe2f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.misc.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.misc-expected.html">
+<title>Canvas test: 2d.reset.render.misc</title>
+<h1>2d.reset.render.misc</h1>
+<p class="desc">check that canvas correctly renders rectangles after reset (states not covered by other tests)</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = "red";
+ ctx.strokeStyle = "red";
+ ctx.globalAlpha = 0.5;
+ ctx.filter = "blur(2px)";
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 100, 100);
+ ctx.strokeRect(150, 150, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit-expected.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit-expected.html
new file mode 100644
index 0000000000..c91f485c53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.miter_limit</title>
+<h1>2d.reset.render.miter_limit</h1>
+<p class="desc">check that the lines are correctly rendered with the default miter limit after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 10;
+
+ ctx.beginPath();
+ ctx.moveTo(0, 100);
+ for (let i = 0; i < 24; i++) {
+ const dy = i % 2 === 0 ? 25 : -25;
+ ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
+ }
+ ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit.html
new file mode 100644
index 0000000000..f6eaed00f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.miter_limit.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.miter_limit-expected.html">
+<title>Canvas test: 2d.reset.render.miter_limit</title>
+<h1>2d.reset.render.miter_limit</h1>
+<p class="desc">check that the lines are correctly rendered with the default miter limit after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.miterLimit = 6;
+
+ ctx.reset();
+
+ ctx.lineWidth = 10;
+
+ ctx.beginPath();
+ ctx.moveTo(0, 100);
+ for (let i = 0; i < 24; i++) {
+ const dy = i % 2 === 0 ? 25 : -25;
+ ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
+ }
+ ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text-expected.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text-expected.html
new file mode 100644
index 0000000000..7221483b02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.text</title>
+<h1>2d.reset.render.text</h1>
+<p class="desc">check that text is correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillText("Lorem ipsum dolor sit amet, consectetur adipiscing elit", 0, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text.html
new file mode 100644
index 0000000000..3d76ddf292
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.render.text.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.text-expected.html">
+<title>Canvas test: 2d.reset.render.text</title>
+<h1>2d.reset.render.text</h1>
+<p class="desc">check that text is correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "24px serif";
+ ctx.textAlign = "center";
+ ctx.textBaseline = "hanging";
+ ctx.direction = "rtl";
+ ctx.letterSpacing = "10px";
+ ctx.fontKerning = "none";
+ ctx.fontStretch = "semi-condensed";
+ ctx.fontVariantCaps = "tilting-caps";
+ ctx.textRendering = "optimizeLegibility";
+ ctx.wordSpacing = "20px";
+
+ ctx.reset();
+
+ ctx.fillText("Lorem ipsum dolor sit amet, consectetur adipiscing elit", 0, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip-expected.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip-expected.html
new file mode 100644
index 0000000000..974b37fab4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.clip</title>
+<h1>2d.reset.state.clip</h1>
+<p class="desc">check that the clip is reset</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(0, 0, 200, 200);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip.html
new file mode 100644
index 0000000000..ab3fa1081c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.clip.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.state.clip-expected.html">
+<title>Canvas test: 2d.reset.state.clip</title>
+<h1>2d.reset.state.clip</h1>
+<p class="desc">check that the clip is reset</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.clip();
+
+ ctx.fillRect(0, 0, 200, 200);
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 200, 200);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.direction.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.direction.html
new file mode 100644
index 0000000000..8b27e3cfe4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.direction.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.direction</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.direction</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.direction;
+
+ ctx.direction = 'rtl';
+ _assert(ctx.direction == 'rtl', "ctx.direction == 'rtl'");
+
+ ctx.reset();
+ _assert(ctx.direction == default_value, "ctx.direction == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.fill_style.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.fill_style.html
new file mode 100644
index 0000000000..1239e2ec7f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.fill_style.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.fill_style</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.fill_style</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.fillStyle;
+
+ ctx.fillStyle = '#ffffff';
+ _assert(ctx.fillStyle == '#ffffff', "ctx.fillStyle == '#ffffff'");
+
+ ctx.reset();
+ _assert(ctx.fillStyle == default_value, "ctx.fillStyle == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.filter.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.filter.html
new file mode 100644
index 0000000000..80ccd22bb2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.filter.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.filter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.filter</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.filter;
+
+ ctx.filter = 'blur(10px)';
+ _assert(ctx.filter == 'blur(10px)', "ctx.filter == 'blur(10px)'");
+
+ ctx.reset();
+ _assert(ctx.filter == default_value, "ctx.filter == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font.html
new file mode 100644
index 0000000000..c93d038a62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.font</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.font</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.font;
+
+ ctx.font = '16px sans-serif';
+ _assert(ctx.font == '16px sans-serif', "ctx.font == '16px sans-serif'");
+
+ ctx.reset();
+ _assert(ctx.font == default_value, "ctx.font == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_kerning.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_kerning.html
new file mode 100644
index 0000000000..d3ad9d386c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_kerning.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.font_kerning</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.font_kerning</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.fontKerning;
+
+ ctx.fontKerning = 'normal';
+ _assert(ctx.fontKerning == 'normal', "ctx.fontKerning == 'normal'");
+
+ ctx.reset();
+ _assert(ctx.fontKerning == default_value, "ctx.fontKerning == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_stretch.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_stretch.html
new file mode 100644
index 0000000000..0a91c640b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_stretch.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.font_stretch</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.font_stretch</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.fontStretch;
+
+ ctx.fontStretch = 'ultra-condensed';
+ _assert(ctx.fontStretch == 'ultra-condensed', "ctx.fontStretch == 'ultra-condensed'");
+
+ ctx.reset();
+ _assert(ctx.fontStretch == default_value, "ctx.fontStretch == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_variant_caps.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_variant_caps.html
new file mode 100644
index 0000000000..262c4fc4d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.font_variant_caps.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.font_variant_caps</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.font_variant_caps</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.fontVariantCaps;
+
+ ctx.fontVariantCaps = 'unicase';
+ _assert(ctx.fontVariantCaps == 'unicase', "ctx.fontVariantCaps == 'unicase'");
+
+ ctx.reset();
+ _assert(ctx.fontVariantCaps == default_value, "ctx.fontVariantCaps == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_alpha.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_alpha.html
new file mode 100644
index 0000000000..18b825e60f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_alpha.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.global_alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.global_alpha</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.globalAlpha;
+
+ ctx.globalAlpha = 0.5;
+ _assert(ctx.globalAlpha == 0.5, "ctx.globalAlpha == 0.5");
+
+ ctx.reset();
+ _assert(ctx.globalAlpha == default_value, "ctx.globalAlpha == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_composite_operation.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_composite_operation.html
new file mode 100644
index 0000000000..aee6841d95
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.global_composite_operation.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.global_composite_operation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.global_composite_operation</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.globalCompositeOperation;
+
+ ctx.globalCompositeOperation = 'destination-over';
+ _assert(ctx.globalCompositeOperation == 'destination-over', "ctx.globalCompositeOperation == 'destination-over'");
+
+ ctx.reset();
+ _assert(ctx.globalCompositeOperation == default_value, "ctx.globalCompositeOperation == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_enabled.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_enabled.html
new file mode 100644
index 0000000000..e865967a38
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_enabled.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.image_smoothing_enabled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.image_smoothing_enabled</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.imageSmoothingEnabled;
+
+ ctx.imageSmoothingEnabled = false;
+ _assert(ctx.imageSmoothingEnabled == false, "ctx.imageSmoothingEnabled == false");
+
+ ctx.reset();
+ _assert(ctx.imageSmoothingEnabled == default_value, "ctx.imageSmoothingEnabled == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_quality.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_quality.html
new file mode 100644
index 0000000000..e78abfce77
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.image_smoothing_quality.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.image_smoothing_quality</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.image_smoothing_quality</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.imageSmoothingQuality;
+
+ ctx.imageSmoothingQuality = 'high';
+ _assert(ctx.imageSmoothingQuality == 'high', "ctx.imageSmoothingQuality == 'high'");
+
+ ctx.reset();
+ _assert(ctx.imageSmoothingQuality == default_value, "ctx.imageSmoothingQuality == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.letter_spacing.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.letter_spacing.html
new file mode 100644
index 0000000000..3e732b1fa0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.letter_spacing.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.letter_spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.letter_spacing</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.letterSpacing;
+
+ ctx.letterSpacing = '12px';
+ _assert(ctx.letterSpacing == '12px', "ctx.letterSpacing == '12px'");
+
+ ctx.reset();
+ _assert(ctx.letterSpacing == default_value, "ctx.letterSpacing == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_cap.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_cap.html
new file mode 100644
index 0000000000..8020e284a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_cap.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.line_cap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.line_cap</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.lineCap;
+
+ ctx.lineCap = 'square';
+ _assert(ctx.lineCap == 'square', "ctx.lineCap == 'square'");
+
+ ctx.reset();
+ _assert(ctx.lineCap == default_value, "ctx.lineCap == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash.html
new file mode 100644
index 0000000000..ca68ae5158
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.line_dash</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.line_dash</h1>
+<p class="desc">check that the line dash is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the line dash is reset");
+_addTest(function(canvas, ctx) {
+
+ ctx.setLineDash([1, 2]);
+
+ ctx.reset();
+ _assert(ctx.getLineDash().length == 0, "ctx.getLineDash().length == 0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash_offset.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash_offset.html
new file mode 100644
index 0000000000..10015199b9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_dash_offset.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.line_dash_offset</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.line_dash_offset</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.lineDashOffset;
+
+ ctx.lineDashOffset = 1.0;
+ _assert(ctx.lineDashOffset == 1.0, "ctx.lineDashOffset == 1.0");
+
+ ctx.reset();
+ _assert(ctx.lineDashOffset == default_value, "ctx.lineDashOffset == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_join.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_join.html
new file mode 100644
index 0000000000..1c20cb1b2a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_join.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.line_join</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.line_join</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.lineJoin;
+
+ ctx.lineJoin = 'bevel';
+ _assert(ctx.lineJoin == 'bevel', "ctx.lineJoin == 'bevel'");
+
+ ctx.reset();
+ _assert(ctx.lineJoin == default_value, "ctx.lineJoin == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_width.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_width.html
new file mode 100644
index 0000000000..db2516b535
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.line_width.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.line_width</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.line_width</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.lineWidth;
+
+ ctx.lineWidth = 1;
+ _assert(ctx.lineWidth == 1, "ctx.lineWidth == 1");
+
+ ctx.reset();
+ _assert(ctx.lineWidth == default_value, "ctx.lineWidth == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.miter_limit.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.miter_limit.html
new file mode 100644
index 0000000000..7920c38d52
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.miter_limit.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.miter_limit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.miter_limit</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.miterLimit;
+
+ ctx.miterLimit = 1.0;
+ _assert(ctx.miterLimit == 1.0, "ctx.miterLimit == 1.0");
+
+ ctx.reset();
+ _assert(ctx.miterLimit == default_value, "ctx.miterLimit == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_blur.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_blur.html
new file mode 100644
index 0000000000..07784de7d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_blur.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.shadow_blur</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.shadow_blur</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.shadowBlur;
+
+ ctx.shadowBlur = 10.0;
+ _assert(ctx.shadowBlur == 10.0, "ctx.shadowBlur == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowBlur == default_value, "ctx.shadowBlur == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_color.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_color.html
new file mode 100644
index 0000000000..9e8ee6c7f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_color.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.shadow_color</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.shadow_color</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.shadowColor;
+
+ ctx.shadowColor = '#ff0000';
+ _assert(ctx.shadowColor == '#ff0000', "ctx.shadowColor == '#ff0000'");
+
+ ctx.reset();
+ _assert(ctx.shadowColor == default_value, "ctx.shadowColor == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_x.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_x.html
new file mode 100644
index 0000000000..7992ce4c1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_x.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.shadow_offset_x</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.shadow_offset_x</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.shadowOffsetX;
+
+ ctx.shadowOffsetX = 10.0;
+ _assert(ctx.shadowOffsetX == 10.0, "ctx.shadowOffsetX == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowOffsetX == default_value, "ctx.shadowOffsetX == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_y.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_y.html
new file mode 100644
index 0000000000..84a38e0bdb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.shadow_offset_y.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.shadow_offset_y</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.shadow_offset_y</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.shadowOffsetY;
+
+ ctx.shadowOffsetY = 10.0;
+ _assert(ctx.shadowOffsetY == 10.0, "ctx.shadowOffsetY == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowOffsetY == default_value, "ctx.shadowOffsetY == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.stroke_style.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.stroke_style.html
new file mode 100644
index 0000000000..4acb19c41e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.stroke_style.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.stroke_style</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.stroke_style</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.strokeStyle;
+
+ ctx.strokeStyle = '#ffffff';
+ _assert(ctx.strokeStyle == '#ffffff', "ctx.strokeStyle == '#ffffff'");
+
+ ctx.reset();
+ _assert(ctx.strokeStyle == default_value, "ctx.strokeStyle == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_align.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_align.html
new file mode 100644
index 0000000000..a625737d72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_align.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.text_align</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.text_align</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.textAlign;
+
+ ctx.textAlign = 'end';
+ _assert(ctx.textAlign == 'end', "ctx.textAlign == 'end'");
+
+ ctx.reset();
+ _assert(ctx.textAlign == default_value, "ctx.textAlign == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_baseline.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_baseline.html
new file mode 100644
index 0000000000..2e4169bdb1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_baseline.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.text_baseline</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.text_baseline</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.textBaseline;
+
+ ctx.textBaseline = 'middle';
+ _assert(ctx.textBaseline == 'middle', "ctx.textBaseline == 'middle'");
+
+ ctx.reset();
+ _assert(ctx.textBaseline == default_value, "ctx.textBaseline == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_rendering.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_rendering.html
new file mode 100644
index 0000000000..e182babee4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.text_rendering.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.text_rendering</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.text_rendering</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.textRendering;
+
+ ctx.textRendering = 'geometricPrecision';
+ _assert(ctx.textRendering == 'geometricPrecision', "ctx.textRendering == 'geometricPrecision'");
+
+ ctx.reset();
+ _assert(ctx.textRendering == default_value, "ctx.textRendering == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.transformation_matrix.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.transformation_matrix.html
new file mode 100644
index 0000000000..7872681bfc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.transformation_matrix.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.transformation_matrix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.transformation_matrix</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ ctx.scale(2, 2);
+
+ ctx.reset();
+ _assert(ctx.getTransform().isIdentity, "ctx.getTransform().isIdentity");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.word_spacing.html b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.word_spacing.html
new file mode 100644
index 0000000000..c4a448f21c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/reset/2d.reset.state.word_spacing.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.word_spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.reset.state.word_spacing</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("check that the state is reset");
+_addTest(function(canvas, ctx) {
+
+ const default_value = ctx.wordSpacing;
+
+ ctx.wordSpacing = '12px';
+ _assert(ctx.wordSpacing == '12px', "ctx.wordSpacing == '12px'");
+
+ ctx.reset();
+ _assert(ctx.wordSpacing == default_value, "ctx.wordSpacing == default_value");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.basic.html b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.basic.html
new file mode 100644
index 0000000000..e4cf8ea9ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.basic.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.scrollPathIntoView.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.scrollPathIntoView.basic</h1>
+<p class="desc">scrollPathIntoView() works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("scrollPathIntoView() works");
+_addTest(function(canvas, ctx) {
+
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ _assertSame(Math.round(rect.top), -8, "Math.round(rect.top)", "-8");
+ _assertSame(Math.round(rect.left), 200, "Math.round(rect.left)", "200");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.path.html b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.path.html
new file mode 100644
index 0000000000..ee1f833aaf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.path.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.scrollPathIntoView.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.scrollPathIntoView.path</h1>
+<p class="desc">scrollPathIntoView() with path argument works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("scrollPathIntoView() with path argument works");
+_addTest(function(canvas, ctx) {
+
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ var path = new Path2D();
+ path.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView(path);
+ var rect = canvas.getBoundingClientRect();
+ _assertSame(Math.round(rect.top), -8, "Math.round(rect.top)", "-8");
+ _assertSame(Math.round(rect.left), 200, "Math.round(rect.left)", "200");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalLR.html b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalLR.html
new file mode 100644
index 0000000000..9d09980b6f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalLR.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.scrollPathIntoView.verticalLR</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.scrollPathIntoView.verticalLR</h1>
+<p class="desc">scrollPathIntoView() works in vertical-lr writing mode</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("scrollPathIntoView() works in vertical-lr writing mode");
+_addTest(function(canvas, ctx) {
+
+ document.documentElement.style.cssText = 'writing-mode: vertical-lr';
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ _assertSame(Math.round(rect.top), 100, "Math.round(rect.top)", "100");
+ _assertSame(Math.round(rect.left), -4, "Math.round(rect.left)", "-4");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalRL.html b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalRL.html
new file mode 100644
index 0000000000..8193106f8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/scroll/2d.scrollPathIntoView.verticalRL.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.scrollPathIntoView.verticalRL</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.scrollPathIntoView.verticalRL</h1>
+<p class="desc">scrollPathIntoView() works in vertical-rl writing mode</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("scrollPathIntoView() works in vertical-rl writing mode");
+_addTest(function(canvas, ctx) {
+
+ document.documentElement.style.cssText = 'writing-mode: vertical-rl';
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; right: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ var viewportWidth = document.scrollingElement.clientWidth;
+ var canvasWidth = canvas.width;
+ _assertSame(Math.round(rect.top), 100, "Math.round(rect.top)", "100");
+ _assertSame(Math.round(rect.right), viewportWidth + (canvasWidth - 4 - 16), "Math.round(rect.right)", "viewportWidth + (canvasWidth - 4 - 16)");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.1.html
new file mode 100644
index 0000000000..8888ae6885
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.1.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.alpha.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.alpha.1</h1>
+<p class="desc">Shadow color alpha components are used</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadow color alpha components are used");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(255, 0, 0, 0.01)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 4);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.html
new file mode 100644
index 0000000000..534d3dd16d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.alpha.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.alpha.2</h1>
+<p class="desc">Shadow color alpha components are used</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.alpha.2.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadow color alpha components are used");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.5)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.html
new file mode 100644
index 0000000000..468228208c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.alpha.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.alpha.3</h1>
+<p class="desc">Shadows are affected by globalAlpha</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.alpha.3.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are affected by globalAlpha");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.5;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.html
new file mode 100644
index 0000000000..2932c9dfe1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.alpha.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.alpha.4</h1>
+<p class="desc">Shadows with alpha components are correctly affected by globalAlpha</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.alpha.4.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows with alpha components are correctly affected by globalAlpha");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.707)';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.707;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.html
new file mode 100644
index 0000000000..ffa9ed8fde
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.alpha.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.alpha.5</h1>
+<p class="desc">Shadows of shapes with alpha components are drawn correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.alpha.5.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows of shapes with alpha components are drawn correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgba(64, 0, 0, 0.5)';
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.alpha.5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.initial.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.initial.html
new file mode 100644
index 0000000000..b688156546
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.initial.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowBlur.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowBlur.initial</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.invalid.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.invalid.html
new file mode 100644
index 0000000000..68f5dd41bc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.invalid.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowBlur.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowBlur.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -2;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = Infinity;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -Infinity;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = NaN;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = 'string';
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = true;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = false;
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.valid.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.valid.html
new file mode 100644
index 0000000000..51063a6ade
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowBlur.valid.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowBlur.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowBlur.valid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.shadowBlur = 1;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 0.5;
+ _assertSame(ctx.shadowBlur, 0.5, "ctx.shadowBlur", "0.5");
+
+ ctx.shadowBlur = 1e6;
+ _assertSame(ctx.shadowBlur, 1e6, "ctx.shadowBlur", "1e6");
+
+ ctx.shadowBlur = 0;
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.basic.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.basic.html
new file mode 100644
index 0000000000..bfdc54d31b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.basic.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowColor.current.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowColor.current.basic</h1>
+<p class="desc">currentColor is computed from the canvas element</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("currentColor is computed from the canvas element");
+_addTest(function(canvas, ctx) {
+
+ canvas.style.color = '#0f0';
+ ctx.shadowColor = 'currentColor';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.changed.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.changed.html
new file mode 100644
index 0000000000..9eee2122d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.changed.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowColor.current.changed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowColor.current.changed</h1>
+<p class="desc">currentColor is computed when the attribute is set, not when it is painted</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("currentColor is computed when the attribute is set, not when it is painted");
+_addTest(function(canvas, ctx) {
+
+ canvas.style.color = '#0f0';
+ ctx.shadowColor = 'currentColor';
+ canvas.style.color = '#f00';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.removed.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.removed.html
new file mode 100644
index 0000000000..e1989cbdc8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.current.removed.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowColor.current.removed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowColor.current.removed</h1>
+<p class="desc">currentColor is solid black when the canvas element is not in a document</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("currentColor is solid black when the canvas element is not in a document");
+_addTest(function(canvas, ctx) {
+
+ // Try not to let it undetectably incorrectly pick up opaque-black
+ // from other parts of the document:
+ document.documentElement.style.color = '#f00';
+ document.body.style.color = '#f00';
+ canvas.style.color = '#f00';
+
+ canvas.remove();
+ ctx.shadowColor = 'currentColor';
+ _assertSame(ctx.shadowColor, '#000000', "ctx.shadowColor", "'#000000'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.initial.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.initial.html
new file mode 100644
index 0000000000..f4d0d33d6d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.initial.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowColor.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowColor.initial</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.shadowColor, 'rgba(0, 0, 0, 0)', "ctx.shadowColor", "'rgba(0, 0, 0, 0)'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.invalid.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.invalid.html
new file mode 100644
index 0000000000..73f835dd96
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.invalid.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowColor.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowColor.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'bogus';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'red bogus';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = ctx;
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = undefined;
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.valid.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.valid.html
new file mode 100644
index 0000000000..bc86c3d6c1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowColor.valid.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowColor.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowColor.valid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.shadowColor = 'lime';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = 'RGBA(0,255, 0,0)';
+ _assertSame(ctx.shadowColor, 'rgba(0, 255, 0, 0)', "ctx.shadowColor", "'rgba(0, 255, 0, 0)'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.initial.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.initial.html
new file mode 100644
index 0000000000..056dd1607b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.initial.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowOffset.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowOffset.initial</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.invalid.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.invalid.html
new file mode 100644
index 0000000000..1567edb16a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.invalid.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowOffset.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowOffset.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = Infinity;
+ ctx.shadowOffsetY = Infinity;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = -Infinity;
+ ctx.shadowOffsetY = -Infinity;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = NaN;
+ ctx.shadowOffsetY = NaN;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = 'string';
+ ctx.shadowOffsetY = 'string';
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = true;
+ ctx.shadowOffsetY = true;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 1, "ctx.shadowOffsetY", "1");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = false;
+ ctx.shadowOffsetY = false;
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.valid.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.valid.html
new file mode 100644
index 0000000000..04fe18c391
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.attributes.shadowOffset.valid.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.attributes.shadowOffset.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.attributes.shadowOffset.valid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 0.5;
+ ctx.shadowOffsetY = 0.25;
+ _assertSame(ctx.shadowOffsetX, 0.5, "ctx.shadowOffsetX", "0.5");
+ _assertSame(ctx.shadowOffsetY, 0.25, "ctx.shadowOffsetY", "0.25");
+
+ ctx.shadowOffsetX = -0.5;
+ ctx.shadowOffsetY = -0.25;
+ _assertSame(ctx.shadowOffsetX, -0.5, "ctx.shadowOffsetX", "-0.5");
+ _assertSame(ctx.shadowOffsetY, -0.25, "ctx.shadowOffsetY", "-0.25");
+
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 0;
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+
+ ctx.shadowOffsetX = 1e6;
+ ctx.shadowOffsetY = 1e6;
+ _assertSame(ctx.shadowOffsetX, 1e6, "ctx.shadowOffsetX", "1e6");
+ _assertSame(ctx.shadowOffsetY, 1e6, "ctx.shadowOffsetY", "1e6");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high-manual.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high-manual.html
new file mode 100644
index 0000000000..aae0a163bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.blur.high</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.blur.high</h1>
+<p class="desc">Shadows look correct for large blurs</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.blur.high.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows look correct for large blurs");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 0;
+ ctx.shadowBlur = 100;
+ ctx.fillRect(-200, -200, 200, 400);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high.png
new file mode 100644
index 0000000000..743640b79f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.high.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low-manual.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low-manual.html
new file mode 100644
index 0000000000..9674d6f0db
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low-manual.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.blur.low</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.blur.low</h1>
+<p class="desc">Shadows look correct for small blurs</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.blur.low.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows look correct for small blurs");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 25;
+ for (var x = 0; x < 100; ++x) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(x, 0, 1, 50);
+ ctx.clip();
+ ctx.shadowBlur = x;
+ ctx.fillRect(-200, -200, 500, 200);
+ ctx.restore();
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low.png
new file mode 100644
index 0000000000..99fb651c21
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.blur.low.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.html
new file mode 100644
index 0000000000..18818fa726
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.canvas.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.canvas.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent canvases</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.canvas.alpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn correctly for partially-transparent canvases");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = 'rgba(255, 0, 0, 0.5)';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.basic.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.basic.html
new file mode 100644
index 0000000000..e752c8f180
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.basic.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.canvas.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.canvas.basic</h1>
+<p class="desc">Shadows are drawn for canvases</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for canvases");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.1.html
new file mode 100644
index 0000000000..7d159328a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.canvas.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.canvas.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent canvases</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent canvases");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.2.html
new file mode 100644
index 0000000000..4326d42bbe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.canvas.transparent.2.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.canvas.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.canvas.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of canvases</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent parts of canvases");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.drawImage(canvas2, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(canvas2, -50, -50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.1.html
new file mode 100644
index 0000000000..6caff8b92f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.1.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.clip.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.clip.1</h1>
+<p class="desc">Shadows of clipped shapes are still drawn within the clipping region</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows of clipped shapes are still drawn within the clipping region");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.2.html
new file mode 100644
index 0000000000..a5b05237e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.2.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.clip.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.clip.2</h1>
+<p class="desc">Shadows are not drawn outside the clipping region</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn outside the clipping region");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.3.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.3.html
new file mode 100644
index 0000000000..b7652634fb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.clip.3.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.clip.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.clip.3</h1>
+<p class="desc">Shadows of clipped shapes are still drawn within the clipping region</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows of clipped shapes are still drawn within the clipping region");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.1.html
new file mode 100644
index 0000000000..d64ecb4972
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.composite.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.composite.1</h1>
+<p class="desc">Shadows are drawn using globalCompositeOperation</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn using globalCompositeOperation");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, 0, 200, 50);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.2.html
new file mode 100644
index 0000000000..abc6b98d72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.composite.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.composite.2</h1>
+<p class="desc">Shadows are drawn using globalCompositeOperation</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn using globalCompositeOperation");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-10, -10, 120, 70);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.3.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.3.html
new file mode 100644
index 0000000000..45eebd9eb0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.composite.3.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.composite.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.composite.3</h1>
+<p class="desc">Areas outside shadows are drawn correctly with destination-out</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Areas outside shadows are drawn correctly with destination-out");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 10;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(200, 0, 100, 50);
+
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.blur.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.blur.html
new file mode 100644
index 0000000000..7efa459c29
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.blur.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.enable.blur</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.enable.blur</h1>
+<p class="desc">Shadows are drawn if shadowBlur is set</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn if shadowBlur is set");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.1.html
new file mode 100644
index 0000000000..953ea04277
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.enable.off.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.enable.off.1</h1>
+<p class="desc">Shadows are not drawn when only shadowColor is set</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn when only shadowColor is set");
+_addTest(function(canvas, ctx) {
+
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.2.html
new file mode 100644
index 0000000000..2a8cf7301d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.off.2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.enable.off.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.enable.off.2</h1>
+<p class="desc">Shadows are not drawn when only shadowColor is set</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn when only shadowColor is set");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.x.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.x.html
new file mode 100644
index 0000000000..6eae985fd6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.x.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.enable.x</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.enable.x</h1>
+<p class="desc">Shadows are drawn if shadowOffsetX is set</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn if shadowOffsetX is set");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.y.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.y.html
new file mode 100644
index 0000000000..2025babca6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.enable.y.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.enable.y</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.enable.y</h1>
+<p class="desc">Shadows are drawn if shadowOffsetY is set</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn if shadowOffsetY is set");
+_addTest(function(canvas, ctx) {
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.html
new file mode 100644
index 0000000000..65f4fdad27
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.gradient.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.gradient.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent gradient fills</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.gradient.alpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn correctly for partially-transparent gradient fills");
+_addTest(function(canvas, ctx) {
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(255,0,0,0.5)');
+ gradient.addColorStop(1, 'rgba(255,0,0,0.5)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.basic.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.basic.html
new file mode 100644
index 0000000000..a7c5efe738
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.gradient.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.gradient.basic</h1>
+<p class="desc">Shadows are drawn for gradient fills</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for gradient fills");
+_addTest(function(canvas, ctx) {
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(1, '#f00');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.1.html
new file mode 100644
index 0000000000..1c11f75e80
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.gradient.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.gradient.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent gradient fills</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent gradient fills");
+_addTest(function(canvas, ctx) {
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.2.html
new file mode 100644
index 0000000000..244aecab21
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.gradient.transparent.2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.gradient.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.gradient.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of gradient fills</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent parts of gradient fills");
+_addTest(function(canvas, ctx) {
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(0.499, '#f00');
+ gradient.addColorStop(0.5, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.html
new file mode 100644
index 0000000000..f00e1752df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.image.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.image.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent images</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.image.alpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn correctly for partially-transparent images");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ var img = document.getElementById('transparent50.png');
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+<img src="/images/transparent50.png" id="transparent50.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.basic.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.basic.html
new file mode 100644
index 0000000000..d106e223db
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.basic.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.image.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.image.basic</h1>
+<p class="desc">Shadows are drawn for images</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for images");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ var img = document.getElementById('red.png');
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.scale.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.scale.html
new file mode 100644
index 0000000000..7e07fff378
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.scale.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.image.scale</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.image.scale</h1>
+<p class="desc">Shadows are drawn correctly for scaled images</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn correctly for scaled images");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ var img = document.getElementById('redtransparent.png');
+ ctx.drawImage(img, 0, 0, 100, 50, -10, -50, 240, 50);
+
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+});
+</script>
+<img src="/images/redtransparent.png" id="redtransparent.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.section.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.section.html
new file mode 100644
index 0000000000..a1b3e7032f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.section.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.image.section</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.image.section</h1>
+<p class="desc">Shadows are not drawn for areas outside image source rectangles</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for areas outside image source rectangles");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#f00';
+ var img = document.getElementById('redtransparent.png');
+ ctx.drawImage(img, 50, 0, 50, 50, 0, -50, 50, 50);
+
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+});
+</script>
+<img src="/images/redtransparent.png" id="redtransparent.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.1.html
new file mode 100644
index 0000000000..74d8b22951
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.image.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.image.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent images</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent images");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ var img = document.getElementById('transparent.png');
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+<img src="/images/transparent.png" id="transparent.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.2.html
new file mode 100644
index 0000000000..1a52a52c3f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.image.transparent.2.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.image.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.image.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of images</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent parts of images");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ var img = document.getElementById('redtransparent.png');
+ ctx.drawImage(img, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(img, -50, -50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+<img src="/images/redtransparent.png" id="redtransparent.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeX.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeX.html
new file mode 100644
index 0000000000..0a73b07b6c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeX.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.offset.negativeX</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.offset.negativeX</h1>
+<p class="desc">Shadows can be offset with negative x</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows can be offset with negative x");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = -50;
+ ctx.fillRect(50, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeY.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeY.html
new file mode 100644
index 0000000000..04c9620fd2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.negativeY.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.offset.negativeY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.offset.negativeY</h1>
+<p class="desc">Shadows can be offset with negative y</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows can be offset with negative y");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = -25;
+ ctx.fillRect(0, 25, 100, 25);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveX.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveX.html
new file mode 100644
index 0000000000..1254474385
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveX.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.offset.positiveX</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.offset.positiveX</h1>
+<p class="desc">Shadows can be offset with positive x</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows can be offset with positive x");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveY.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveY.html
new file mode 100644
index 0000000000..fdcf25a435
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.offset.positiveY.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.offset.positiveY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.offset.positiveY</h1>
+<p class="desc">Shadows can be offset with positive y</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows can be offset with positive y");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 25;
+ ctx.fillRect(0, 0, 100, 25);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.outside.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.outside.html
new file mode 100644
index 0000000000..fcf2129488
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.outside.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.outside</h1>
+<p class="desc">Shadows of shapes outside the visible area can be offset onto the visible area</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows of shapes outside the visible area can be offset onto the visible area");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.fillRect(-100, 0, 25, 50);
+ ctx.shadowOffsetX = -100;
+ ctx.fillRect(175, 0, 25, 50);
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 100;
+ ctx.fillRect(25, -100, 50, 25);
+ ctx.shadowOffsetY = -100;
+ ctx.fillRect(25, 125, 50, 25);
+ _assertPixel(canvas, 12,25, 0,255,0,255);
+ _assertPixel(canvas, 87,25, 0,255,0,255);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.html
new file mode 100644
index 0000000000..10b5414b12
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.pattern.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.pattern.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent fill patterns</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.shadow.pattern.alpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn correctly for partially-transparent fill patterns");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('transparent50.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+});
+</script>
+<img src="/images/transparent50.png" id="transparent50.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.png b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.basic.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.basic.html
new file mode 100644
index 0000000000..47d2149a57
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.pattern.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.pattern.basic</h1>
+<p class="desc">Shadows are drawn for fill patterns</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for fill patterns");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('red.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+<img src="/images/red.png" id="red.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.1.html
new file mode 100644
index 0000000000..c41dd83778
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.pattern.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.pattern.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent fill patterns</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent fill patterns");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('transparent.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+<img src="/images/transparent.png" id="transparent.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.2.html
new file mode 100644
index 0000000000..ddaf21fe90
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.pattern.transparent.2.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.pattern.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.pattern.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of fill patterns</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for transparent parts of fill patterns");
+_addTest(function(canvas, ctx) {
+
+ var img = document.getElementById('redtransparent.png');
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+<img src="/images/redtransparent.png" id="redtransparent.png" class="resource">
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.basic.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.basic.html
new file mode 100644
index 0000000000..6146ba7d19
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.basic.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.stroke.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.stroke.basic</h1>
+<p class="desc">Shadows are drawn for strokes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for strokes");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, -25);
+ ctx.lineTo(100, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.1.html
new file mode 100644
index 0000000000..5d6e53a685
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.1.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.stroke.cap.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.stroke.cap.1</h1>
+<p class="desc">Shadows are not drawn for areas outside stroke caps</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for areas outside stroke caps");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'butt';
+ ctx.moveTo(-50, -25);
+ ctx.lineTo(0, -25);
+ ctx.moveTo(100, -25);
+ ctx.lineTo(150, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.2.html
new file mode 100644
index 0000000000..f18a9b6cc5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.cap.2.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.stroke.cap.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.stroke.cap.2</h1>
+<p class="desc">Shadows are drawn for stroke caps</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for stroke caps");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'square';
+ ctx.moveTo(25, -25);
+ ctx.lineTo(75, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.1.html
new file mode 100644
index 0000000000..46735a918f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.1.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.stroke.join.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.stroke.join.1</h1>
+<p class="desc">Shadows are not drawn for areas outside stroke joins</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are not drawn for areas outside stroke joins");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.2.html
new file mode 100644
index 0000000000..85abc24e81
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.2.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.stroke.join.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.stroke.join.2</h1>
+<p class="desc">Shadows are drawn for stroke joins</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for stroke joins");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.3.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.3.html
new file mode 100644
index 0000000000..795c6137d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.stroke.join.3.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.stroke.join.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.stroke.join.3</h1>
+<p class="desc">Shadows are drawn for stroke joins respecting miter limit</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows are drawn for stroke joins respecting miter limit");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 0.1;
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100); // (not an exact right angle, to avoid some other bug in Firefox 3)
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.1.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.1.html
new file mode 100644
index 0000000000..abfb54e5db
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.transform.1</h1>
+<p class="desc">Shadows take account of transformations</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadows take account of transformations");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.translate(100, 100);
+ ctx.fillRect(-100, -150, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.2.html b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.2.html
new file mode 100644
index 0000000000..736dd4efa4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/shadows/2d.shadow.transform.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.shadow.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.shadow.transform.2</h1>
+<p class="desc">Shadow offsets are not affected by transformations</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Shadow offsets are not affected by transformations");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.rotate(Math.PI)
+ ctx.fillRect(-100, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.align.default.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.align.default.html
new file mode 100644
index 0000000000..d32f7831d0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.align.default.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.align.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.align.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.align.invalid.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.align.invalid.html
new file mode 100644
index 0000000000..7b7f33766a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.align.invalid.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.align.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.align.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'bogus';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'END';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end ';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end\0';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.align.valid.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.align.valid.html
new file mode 100644
index 0000000000..a568530f3b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.align.valid.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.align.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.align.valid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.textAlign = 'start';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'end';
+ _assertSame(ctx.textAlign, 'end', "ctx.textAlign", "'end'");
+
+ ctx.textAlign = 'left';
+ _assertSame(ctx.textAlign, 'left', "ctx.textAlign", "'left'");
+
+ ctx.textAlign = 'right';
+ _assertSame(ctx.textAlign, 'right', "ctx.textAlign", "'right'");
+
+ ctx.textAlign = 'center';
+ _assertSame(ctx.textAlign, 'center', "ctx.textAlign", "'center'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.default.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.default.html
new file mode 100644
index 0000000000..08e8512c66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.default.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.baseline.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.baseline.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.textBaseline, 'alphabetic', "ctx.textBaseline", "'alphabetic'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.invalid.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.invalid.html
new file mode 100644
index 0000000000..e527a77288
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.invalid.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.baseline.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.baseline.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'bogus';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'MIDDLE';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle ';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle\0';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.valid.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.valid.html
new file mode 100644
index 0000000000..238f6ff7dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.baseline.valid.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.baseline.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.baseline.valid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.textBaseline = 'top';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'hanging';
+ _assertSame(ctx.textBaseline, 'hanging', "ctx.textBaseline", "'hanging'");
+
+ ctx.textBaseline = 'middle';
+ _assertSame(ctx.textBaseline, 'middle', "ctx.textBaseline", "'middle'");
+
+ ctx.textBaseline = 'alphabetic';
+ _assertSame(ctx.textBaseline, 'alphabetic', "ctx.textBaseline", "'alphabetic'");
+
+ ctx.textBaseline = 'ideographic';
+ _assertSame(ctx.textBaseline, 'ideographic', "ctx.textBaseline", "'ideographic'");
+
+ ctx.textBaseline = 'bottom';
+ _assertSame(ctx.textBaseline, 'bottom', "ctx.textBaseline", "'bottom'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.center.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.center.html
new file mode 100644
index 0000000000..723ebe8764
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.center.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.align.center</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.align.center</h1>
+<p class="desc">textAlign center is the center of the em squares (not the bounding box)</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'center';
+ ctx.fillText('DD', 50, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign center is the center of the em squares (not the bounding box)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.ltr.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.ltr.html
new file mode 100644
index 0000000000..d29da833cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.ltr.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.align.end.ltr</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.align.end.ltr</h1>
+<p class="desc">textAlign end with ltr is the right edge</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"dir="ltr"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign end with ltr is the right edge");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.rtl.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.rtl.html
new file mode 100644
index 0000000000..09a9658ac0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.end.rtl.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.align.end.rtl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.align.end.rtl</h1>
+<p class="desc">textAlign end with rtl is the left edge</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"dir="rtl"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign end with rtl is the left edge");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.left.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.left.html
new file mode 100644
index 0000000000..dda5318fbf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.left.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.align.left</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.align.left</h1>
+<p class="desc">textAlign left is the left of the first em square (not the bounding box)</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'left';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign left is the left of the first em square (not the bounding box)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.right.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.right.html
new file mode 100644
index 0000000000..2b3217278a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.right.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.align.right</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.align.right</h1>
+<p class="desc">textAlign right is the right of the last em square (not the bounding box)</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign right is the right of the last em square (not the bounding box)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.ltr.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.ltr.html
new file mode 100644
index 0000000000..8e14642fc2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.ltr.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.align.start.ltr</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.align.start.ltr</h1>
+<p class="desc">textAlign start with ltr is the left edge</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"dir="ltr"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign start with ltr is the left edge");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.rtl.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.rtl.html
new file mode 100644
index 0000000000..fe1ccd1137
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.align.start.rtl.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.align.start.rtl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.align.start.rtl</h1>
+<p class="desc">textAlign start with rtl is the right edge</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"dir="rtl"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign start with rtl is the right edge");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.alphabetic.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.alphabetic.html
new file mode 100644
index 0000000000..a45db596d0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.alphabetic.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.baseline.alphabetic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.baseline.alphabetic</h1>
+<p class="desc"></p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'alphabetic';
+ ctx.fillText('CC', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.bottom.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.bottom.html
new file mode 100644
index 0000000000..ed1bf002a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.bottom.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.baseline.bottom</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.baseline.bottom</h1>
+<p class="desc">textBaseline bottom is the bottom of the em square (not the bounding box)</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'bottom';
+ ctx.fillText('CC', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textBaseline bottom is the bottom of the em square (not the bounding box)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.hanging.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.hanging.html
new file mode 100644
index 0000000000..2f274b4199
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.hanging.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.baseline.hanging</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.baseline.hanging</h1>
+<p class="desc"></p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'hanging';
+ ctx.fillText('CC', 0, 12.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.ideographic.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.ideographic.html
new file mode 100644
index 0000000000..8d6a12e262
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.ideographic.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.baseline.ideographic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.baseline.ideographic</h1>
+<p class="desc"></p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'ideographic';
+ ctx.fillText('CC', 0, 31.25);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.middle.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.middle.html
new file mode 100644
index 0000000000..5b021a5877
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.middle.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.baseline.middle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.baseline.middle</h1>
+<p class="desc">textBaseline middle is the middle of the em square (not the bounding box)</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'middle';
+ ctx.fillText('CC', 0, 25);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textBaseline middle is the middle of the em square (not the bounding box)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.top.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.top.html
new file mode 100644
index 0000000000..2011514d33
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.baseline.top.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.baseline.top</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.baseline.top</h1>
+<p class="desc">textBaseline top is the top of the em square (not the bounding box)</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'top';
+ ctx.fillText('CC', 0, 0);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textBaseline top is the top of the em square (not the bounding box)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic-manual.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic-manual.html
new file mode 100644
index 0000000000..d3f5df9d01
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.basic</h1>
+<p class="desc">fillText draws filled text</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.text.draw.fill.basic.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText draws filled text");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic.png b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic.png
new file mode 100644
index 0000000000..70d7b046cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.basic.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.NaN.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.NaN.html
new file mode 100644
index 0000000000..9705d28830
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.NaN.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.maxWidth.NaN</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.maxWidth.NaN</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, NaN);
+ _assertGreen(ctx, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.bound.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.bound.html
new file mode 100644
index 0000000000..c5f7dcf119
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.bound.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.maxWidth.bound</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.fill.maxWidth.bound</h1>
+<p class="desc">fillText handles maxWidth based on line size, not bounding box size</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('DD', 0, 37.5, 100);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "fillText handles maxWidth based on line size, not bounding box size");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.fontface.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.fontface.html
new file mode 100644
index 0000000000..7df5553815
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.fontface.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.maxWidth.fontface</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.fill.maxWidth.fontface</h1>
+<p class="desc">fillText works on @font-face fonts</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillText('EEEE', -50, 37.5, 40);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "fillText works on @font-face fonts");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large-manual.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large-manual.html
new file mode 100644
index 0000000000..96bb2e7de1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.maxWidth.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.maxWidth.large</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.text.draw.fill.maxWidth.large.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35, 200);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.png b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.png
new file mode 100644
index 0000000000..70d7b046cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.large.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.negative.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.negative.html
new file mode 100644
index 0000000000..ad50d57608
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.negative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.maxWidth.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.maxWidth.negative</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, -1);
+ _assertGreen(ctx, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.small.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.small.html
new file mode 100644
index 0000000000..75866af406
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.small.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.maxWidth.small</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.maxWidth.small</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', -100, 35, 90);
+ _assertGreen(ctx, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.zero.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.zero.html
new file mode 100644
index 0000000000..a175a57879
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.maxWidth.zero.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.maxWidth.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.maxWidth.zero</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, 0);
+ _assertGreen(ctx, 100, 50);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl-manual.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl-manual.html
new file mode 100644
index 0000000000..6917d7ed6c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.rtl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.rtl</h1>
+<p class="desc">fillText respects Right-To-Left Override characters</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.text.draw.fill.rtl.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText respects Right-To-Left Override characters");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('\u202eFAIL \xa0 \xa0 SSAP', 5, 35);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl.png b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl.png
new file mode 100644
index 0000000000..70d7b046cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.rtl.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.unaffected.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.unaffected.html
new file mode 100644
index 0000000000..94ed31d199
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fill.unaffected.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fill.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.fill.unaffected</h1>
+<p class="desc">fillText does not start a new path or subpath</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("fillText does not start a new path or subpath");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.html
new file mode 100644
index 0000000000..c46ac2084e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fontface</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.fontface</h1>
+<p class="desc"></p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.notinpage.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.notinpage.html
new file mode 100644
index 0000000000..92891fb04f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.notinpage.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fontface.notinpage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.fontface.notinpage</h1>
+<p class="desc">@font-face fonts should work even if they are not used in the page</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "@font-face fonts should work even if they are not used in the page");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.repeat.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.repeat.html
new file mode 100644
index 0000000000..d597540b97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.fontface.repeat.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.fontface.repeat</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.fontface.repeat</h1>
+<p class="desc">Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+
+ await new Promise(resolve => t.step_timeout(resolve, 500));
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.kern.consistent-manual.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.kern.consistent-manual.html
new file mode 100644
index 0000000000..1840ef01b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.kern.consistent-manual.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.kern.consistent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.kern.consistent</h1>
+<p class="desc">Stroked and filled text should have exactly the same kerning so it overlaps</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Stroked and filled text should have exactly the same kerning so it overlaps");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 3;
+ ctx.font = '20px Arial, sans-serif';
+ ctx.fillText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.fillText('ToToToToToToTo', -50, 45);
+ ctx.strokeText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.strokeText('ToToToToToToTo', -50, 45);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.basic.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.basic.html
new file mode 100644
index 0000000000..d4447402aa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.basic.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.space.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.space.basic</h1>
+<p class="desc">U+0020 is rendered the correct size (1em wide)</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', -100, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "U+0020 is rendered the correct size (1em wide)");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.end.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.end.html
new file mode 100644
index 0000000000..5a14dbd514
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.end.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.space.collapse.end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.space.collapse.end</h1>
+<p class="desc">Space characters at the end of a line are NOT collapsed</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('EE ', 100, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+
+}, "Space characters at the end of a line are NOT collapsed");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.nonspace.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.nonspace.html
new file mode 100644
index 0000000000..1fc4203b90
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.nonspace.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.space.collapse.nonspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.space.collapse.nonspace</h1>
+<p class="desc">Non-space characters are not converted to U+0020 and collapsed</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E\x0b EE', -150, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Non-space characters are not converted to U+0020 and collapsed");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.other.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.other.html
new file mode 100644
index 0000000000..ffc82929b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.other.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.space.collapse.other</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.space.collapse.other</h1>
+<p class="desc">Space characters are converted to U+0020, and are NOT collapsed</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dEE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+
+}, "Space characters are converted to U+0020, and are NOT collapsed");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.space.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.space.html
new file mode 100644
index 0000000000..64c14d1a54
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.space.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.space.collapse.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.space.collapse.space</h1>
+<p class="desc">Space characters are converted to U+0020, and are NOT collapsed</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+
+}, "Space characters are converted to U+0020, and are NOT collapsed");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.start.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.start.html
new file mode 100644
index 0000000000..272432c3be
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.space.collapse.start.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.space.collapse.start</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.draw.space.collapse.start</h1>
+<p class="desc">Space characters at the start of a line are NOT collapsed</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText(' EE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 255,0,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Space characters at the start of a line are NOT collapsed");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic-manual.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic-manual.html
new file mode 100644
index 0000000000..1db0f0694e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic-manual.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.stroke.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.stroke.basic</h1>
+<p class="desc">strokeText draws stroked text</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.text.draw.stroke.basic.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeText draws stroked text");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 1;
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeText('PASS', 5, 35);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic.png b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic.png
new file mode 100644
index 0000000000..fb3b5b830d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.basic.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.unaffected.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.unaffected.html
new file mode 100644
index 0000000000..76a36476ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.draw.stroke.unaffected.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.draw.stroke.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.draw.stroke.unaffected</h1>
+<p class="desc">strokeText does not start a new path or subpath</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("strokeText does not start a new path or subpath");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeStyle = '#f00';
+ ctx.strokeText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.absolute.spacing.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.absolute.spacing.html
new file mode 100644
index 0000000000..1207f84e2b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.absolute.spacing.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.absolute.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.absolute.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with absolute length</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing letter spacing and word spacing with absolute length");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.letterSpacing = '3px';
+ _assertSame(ctx.letterSpacing, '3px', "ctx.letterSpacing", "'3px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.wordSpacing = '5px';
+ _assertSame(ctx.letterSpacing, '3px', "ctx.letterSpacing", "'3px'");
+ _assertSame(ctx.wordSpacing, '5px', "ctx.wordSpacing", "'5px'");
+
+ ctx.letterSpacing = '-1px';
+ ctx.wordSpacing = '-1px';
+ _assertSame(ctx.letterSpacing, '-1px', "ctx.letterSpacing", "'-1px'");
+ _assertSame(ctx.wordSpacing, '-1px', "ctx.wordSpacing", "'-1px'");
+
+ ctx.letterSpacing = '1PX';
+ ctx.wordSpacing = '10PX';
+ _assertSame(ctx.letterSpacing, '1px', "ctx.letterSpacing", "'1px'");
+ _assertSame(ctx.wordSpacing, '10px', "ctx.wordSpacing", "'10px'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.font-relative.spacing.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.font-relative.spacing.html
new file mode 100644
index 0000000000..a232ec1602
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.font-relative.spacing.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.font-relative.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.font-relative.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with font-relative length</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing letter spacing and word spacing with font-relative length");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.letterSpacing = '1EX';
+ ctx.wordSpacing = '1EM';
+ _assertSame(ctx.letterSpacing, '1ex', "ctx.letterSpacing", "'1ex'");
+ _assertSame(ctx.wordSpacing, '1em', "ctx.wordSpacing", "'1em'");
+
+ ctx.letterSpacing = '1ch';
+ ctx.wordSpacing = '1ic';
+ _assertSame(ctx.letterSpacing, '1ch', "ctx.letterSpacing", "'1ch'");
+ _assertSame(ctx.wordSpacing, '1ic', "ctx.wordSpacing", "'1ic'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.html
new file mode 100644
index 0000000000..6de9c6eb50
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.fontKerning</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.fontKerning</h1>
+<p class="desc">Testing basic functionalities of fontKerning for canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing basic functionalities of fontKerning for canvas");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "normal";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ width_normal = ctx.measureText("TAWATAVA").width;
+ ctx.fontKerning = "none";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ width_none = ctx.measureText("TAWATAVA").width;
+ _assert(width_normal < width_none, "width_normal < width_none");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.with.uppercase.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.with.uppercase.html
new file mode 100644
index 0000000000..991f35af0d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontKerning.with.uppercase.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.fontKerning.with.uppercase</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.fontKerning.with.uppercase</h1>
+<p class="desc">Testing basic functionalities of fontKerning for canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing basic functionalities of fontKerning for canvas");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "Normal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "normal";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ ctx.fontKerning = "Auto";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "noRmal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NoRMal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NORMAL";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+
+ ctx.fontKerning = "None";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "none";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ ctx.fontKerning = "Auto";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nOne";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nonE";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NONE";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontStretch.settings.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontStretch.settings.html
new file mode 100644
index 0000000000..b19eced891
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontStretch.settings.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.fontStretch.settings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.fontStretch.settings</h1>
+<p class="desc">Testing value setting of fontStretch in Canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing value setting of fontStretch in Canvas");
+_addTest(function(canvas, ctx) {
+
+ // Setting textRendering with lower cases
+ ctx.fontStretch = "ultra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-condensed", "ctx.fontStretch", "\"ultra-condensed\"");
+
+ ctx.fontStretch = "extra-condensed";
+ _assertSame(ctx.fontStretch, "extra-condensed", "ctx.fontStretch", "\"extra-condensed\"");
+
+ ctx.fontStretch = "condensed";
+ _assertSame(ctx.fontStretch, "condensed", "ctx.fontStretch", "\"condensed\"");
+
+ ctx.fontStretch = "semi-condensed";
+ _assertSame(ctx.fontStretch, "semi-condensed", "ctx.fontStretch", "\"semi-condensed\"");
+
+ ctx.fontStretch = "normal";
+ _assertSame(ctx.fontStretch, "normal", "ctx.fontStretch", "\"normal\"");
+
+ ctx.fontStretch = "semi-expanded";
+ _assertSame(ctx.fontStretch, "semi-expanded", "ctx.fontStretch", "\"semi-expanded\"");
+
+ ctx.fontStretch = "expanded";
+ _assertSame(ctx.fontStretch, "expanded", "ctx.fontStretch", "\"expanded\"");
+
+ ctx.fontStretch = "extra-expanded";
+ _assertSame(ctx.fontStretch, "extra-expanded", "ctx.fontStretch", "\"extra-expanded\"");
+
+ ctx.fontStretch = "ultra-expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ // Setting fontStretch with lower cases and upper cases word,
+ // these values should be ignored.
+ ctx.fontStretch = "ulTra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Extra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "cOndensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Semi-Condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "normaL";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "semi-Expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "eXtra-expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "abcd";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontVariant.settings.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontVariant.settings.html
new file mode 100644
index 0000000000..cff5ad183a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.fontVariant.settings.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.fontVariant.settings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.fontVariant.settings</h1>
+<p class="desc">Testing basic functionalities of fontVariant for canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing basic functionalities of fontVariant for canvas");
+_addTest(function(canvas, ctx) {
+
+ // Setting fontVariantCaps with lower cases
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "normal";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "small-caps";
+ _assertSame(ctx.fontVariantCaps, "small-caps", "ctx.fontVariantCaps", "\"small-caps\"");
+
+ ctx.fontVariantCaps = "all-small-caps";
+ _assertSame(ctx.fontVariantCaps, "all-small-caps", "ctx.fontVariantCaps", "\"all-small-caps\"");
+
+ ctx.fontVariantCaps = "petite-caps";
+ _assertSame(ctx.fontVariantCaps, "petite-caps", "ctx.fontVariantCaps", "\"petite-caps\"");
+
+ ctx.fontVariantCaps = "all-petite-caps";
+ _assertSame(ctx.fontVariantCaps, "all-petite-caps", "ctx.fontVariantCaps", "\"all-petite-caps\"");
+
+ ctx.fontVariantCaps = "unicase";
+ _assertSame(ctx.fontVariantCaps, "unicase", "ctx.fontVariantCaps", "\"unicase\"");
+
+ ctx.fontVariantCaps = "titling-caps";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+
+ // Setting fontVariantCaps with mixed-case values is not valid
+ ctx.fontVariantCaps = "nORmal";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+
+ ctx.fontVariantCaps = "normal";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "smaLL-caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "all-small-CAPS";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "pEtitE-caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "All-Petite-Caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "uNIcase";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "titling-CAPS";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ // Setting fontVariantCaps with non-existing font variant.
+ ctx.fontVariantCaps = "titling-caps";
+ ctx.fontVariantCaps = "abcd";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.invalid.spacing.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.invalid.spacing.html
new file mode 100644
index 0000000000..a0b8340b2c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.invalid.spacing.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.invalid.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.invalid.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with invalid units</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing letter spacing and word spacing with invalid units");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ }
+ test_word_spacing('0s');
+ test_word_spacing('1min');
+ test_word_spacing('1deg');
+ test_word_spacing('1pp');
+ test_word_spacing('initial');
+ test_word_spacing('inherit');
+ test_word_spacing('normal');
+ test_word_spacing('none');
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html
new file mode 100644
index 0000000000..daff0cf9d6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.letterSpacing.change.font</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.letterSpacing.change.font</h1>
+<p class="desc">Set letter spacing and word spacing to font dependent value and verify it works after font change.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Set letter spacing and word spacing to font dependent value and verify it works after font change.");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ // Get the width for 'Hello World' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World').width;
+
+ ctx.letterSpacing = '1em';
+ _assertSame(ctx.letterSpacing, '1em', "ctx.letterSpacing", "'1em'");
+ // 1em = 10px. Add 10px after each letter in "Hello World",
+ // makes it 110px longer.
+ var width_with_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
+
+ // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
+ // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World').width;
+ // Now calculate the reference spacing for "Hello World" with no spacing.
+ ctx.letterSpacing = '0em';
+ width_normal = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.measure.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.measure.html
new file mode 100644
index 0000000000..0e4848b6fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.letterSpacing.measure.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.letterSpacing.measure</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.letterSpacing.measure</h1>
+<p class="desc">Testing letter spacing with different length units</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing letter spacing with different length units");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ var width_normal = ctx.measureText('Hello World').width;
+
+ function test_letter_spacing(value, difference_spacing, epsilon) {
+ ctx.letterSpacing = value;
+ _assertSame(ctx.letterSpacing, value, "ctx.letterSpacing", "value");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ width_with_letter_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_letter_spacing, width_normal + difference_spacing, epsilon, "letter spacing doesn't work.");
+ }
+
+ // The first value is the letter Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 11 letters
+ // in 'hello world', so the length difference is always letterSpacing * 11.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 33, 0.1],
+ ['5px', 55, 0.1],
+ ['-2px', -22, 0.1],
+ ['1em', 110, 0.1],
+ ['-0.1em', -11, 0.1],
+ ['1in', 1056, 0.1],
+ ['-0.1cm', -41.65, 0.2],
+ ['-0.6mm', -24,95, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_letter_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.direction.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.direction.html
new file mode 100644
index 0000000000..abe696b196
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.direction.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.measure.direction</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.measure.direction</h1>
+<p class="desc">Measurement should follow text direction</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Measurement should follow text direction");
+_addTest(function(canvas, ctx) {
+
+ ctx.direction = "ltr";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+ ctx.direction = "rtl";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.rtl.text.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.rtl.text.html
new file mode 100644
index 0000000000..e521b09236
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.rtl.text.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.measure.rtl.text</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.measure.rtl.text</h1>
+<p class="desc">Measurement should follow canvas direction instead text direction</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Measurement should follow canvas direction instead text direction");
+_addTest(function(canvas, ctx) {
+
+ metrics = ctx.measureText('اَلْعَرَبِيَّةُ');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.textAlign.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.textAlign.html
new file mode 100644
index 0000000000..2d5a4718c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.measure.textAlign.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.measure.textAlign</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.measure.textAlign</h1>
+<p class="desc">Measurement should be related to textAlignment</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Measurement should be related to textAlignment");
+_addTest(function(canvas, ctx) {
+
+ ctx.textAlign = "right";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight");
+
+ ctx.textAlign = "left"
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.nonfinite.spacing.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.nonfinite.spacing.html
new file mode 100644
index 0000000000..5ba20208e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.nonfinite.spacing.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.nonfinite.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.nonfinite.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with nonfinite inputs</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing letter spacing and word spacing with nonfinite inputs");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ }
+ test_word_spacing(NaN);
+ test_word_spacing(Infinity);
+ test_word_spacing(-Infinity);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.textRendering.settings.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.textRendering.settings.html
new file mode 100644
index 0000000000..dee856842a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.textRendering.settings.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.textRendering.settings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.textRendering.settings</h1>
+<p class="desc">Testing basic functionalities of textRendering in Canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing basic functionalities of textRendering in Canvas");
+_addTest(function(canvas, ctx) {
+
+ // Setting textRendering with correct case.
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizeSpeed";
+ _assertSame(ctx.textRendering, "optimizeSpeed", "ctx.textRendering", "\"optimizeSpeed\"");
+
+ ctx.textRendering = "optimizeLegibility";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "geometricPrecision";
+ _assertSame(ctx.textRendering, "geometricPrecision", "ctx.textRendering", "\"geometricPrecision\"");
+
+ ctx.textRendering = "auto";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ // Setting textRendering with incorrect case is ignored.
+ ctx.textRendering = "OPtimizeSpeed";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "OPtimizELEgibility";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "GeometricPrecision";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizespeed";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizelegibility";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "geometricprecision";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizeLegibility";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "AUTO";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "Auto";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ // Setting textRendering with non-existing font variant.
+ ctx.textRendering = "abcd";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "normal";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "auto";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.change.font.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.change.font.html
new file mode 100644
index 0000000000..8bad1a0447
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.change.font.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.wordSpacing.change.font</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.wordSpacing.change.font</h1>
+<p class="desc">Set word spacing and word spacing to font dependent value and verify it works after font change.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Set word spacing and word spacing to font dependent value and verify it works after font change.");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ // Get the width for 'Hello World, again' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ ctx.wordSpacing = '1em';
+ _assertSame(ctx.wordSpacing, '1em', "ctx.wordSpacing", "'1em'");
+ // 1em = 10px. Add 10px after each word in "Hello World, again",
+ // makes it 20px longer.
+ var width_with_spacing = ctx.measureText('Hello World, again').width;
+ _assertSame(width_with_spacing, width_normal + 20, "width_with_spacing", "width_normal + 20");
+
+ // Changing font to 20px. Without resetting the spacing, 1em wordSpacing
+ // is now 20px, so it's suppose to be 40px longer without any wordSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World, again').width;
+ // Now calculate the reference spacing for "Hello World, again" with no spacing.
+ ctx.wordSpacing = '0em';
+ width_normal = ctx.measureText('Hello World, again').width;
+ _assertSame(width_with_spacing, width_normal + 40, "width_with_spacing", "width_normal + 40");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.measure.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.measure.html
new file mode 100644
index 0000000000..2562477d94
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.drawing.style.wordSpacing.measure.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.drawing.style.wordSpacing.measure</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.drawing.style.wordSpacing.measure</h1>
+<p class="desc">Testing word spacing with different length units</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing word spacing with different length units");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ function test_word_spacing(value, difference_spacing, epsilon) {
+ ctx.wordSpacing = value;
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, value, "ctx.wordSpacing", "value");
+ width_with_word_spacing = ctx.measureText('Hello World, again').width;
+ assert_approx_equals(width_with_word_spacing, width_normal + difference_spacing, epsilon, "word spacing doesn't work.");
+ }
+
+ // The first value is the word Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 2 words
+ // in 'Hello World, again', so the length difference is always wordSpacing * 2.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 6, 0.1],
+ ['5px', 10, 0.1],
+ ['-2px', -4, 0.1],
+ ['1em', 20, 0.1],
+ ['-0.5em', -10, 0.1],
+ ['1in', 192, 0.1],
+ ['-0.1cm', -7.57, 0.2],
+ ['-0.6mm', -4.54, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_word_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.default.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.default.html
new file mode 100644
index 0000000000..c6ac084843
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.default.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ _assertSame(ctx.font, '10px sans-serif', "ctx.font", "'10px sans-serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.basic.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.basic.html
new file mode 100644
index 0000000000..70efec7743
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.basic.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.basic</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = '20px serif';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20PX SERIF';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex.html
new file mode 100644
index 0000000000..12e1d60e56
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.complex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.complex</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = 'small-caps italic 400 12px/2 Unknown Font, sans-serif';
+ _assert(['italic small-caps 12px "Unknown Font", sans-serif', 'italic small-caps 12px Unknown Font, sans-serif'].includes(ctx.font), "['italic small-caps 12px \"Unknown Font\", sans-serif', 'italic small-caps 12px Unknown Font, sans-serif'].includes(ctx.font)");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex2.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex2.html
new file mode 100644
index 0000000000..d85765fcd3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.complex2.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.complex2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.complex2</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = 'small-caps italic 400 12px/2 "Unknown Font #2", sans-serif';
+ _assertSame(ctx.font, 'italic small-caps 12px "Unknown Font #2", sans-serif', "ctx.font", "'italic small-caps 12px \"Unknown Font #2\", sans-serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.family.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.family.html
new file mode 100644
index 0000000000..c53bedbffc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.family.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.family</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.family</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = '20px cursive,fantasy,monospace,sans-serif,serif,UnquotedFont,"QuotedFont\\\\\\","';
+ _assertSame(ctx.font, '20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, "QuotedFont\\\\\\","', "ctx.font", "'20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, \"QuotedFont\\\\\\\\\\\\\",\"'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.invalid.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.invalid.html
new file mode 100644
index 0000000000..4fef0b4846
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.invalid.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.invalid</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = '20px serif';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'bogus';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'inherit';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px {bogus}';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px initial';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px default';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px inherit';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px revert';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x)';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x, 10px serif)';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '1em serif; background: green; margin: 10px';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.default.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.default.html
new file mode 100644
index 0000000000..cb245f18a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.default.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.size.percentage.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.size.percentage.default</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.font = '1000% serif';
+ _assertSame(ctx2.font, '100px serif', "ctx2.font", "'100px serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.html
new file mode 100644
index 0000000000..520231a804
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.size.percentage.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.size.percentage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.size.percentage</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"style="font-size: 144px"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = '50% serif';
+ _assertSame(ctx.font, '72px serif', "ctx.font", "'72px serif'");
+ canvas.setAttribute('style', 'font-size: 100px');
+ _assertSame(ctx.font, '72px serif', "ctx.font", "'72px serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.system.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.system.html
new file mode 100644
index 0000000000..10fa0cb36d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.system.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.system</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.system</h1>
+<p class="desc">System fonts must be computed to explicit values</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("System fonts must be computed to explicit values");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = 'message-box';
+ _assertDifferent(ctx.font, 'message-box', "ctx.font", "'message-box'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.tiny.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.tiny.html
new file mode 100644
index 0000000000..10c9d2a0e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.parse.tiny.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.parse.tiny</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.parse.tiny</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = '1px sans-serif';
+ _assertSame(ctx.font, '1px sans-serif', "ctx.font", "'1px sans-serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.relative_size.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.relative_size.html
new file mode 100644
index 0000000000..97b9718b14
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.relative_size.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.relative_size</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.relative_size</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.font = '1em sans-serif';
+ _assertSame(ctx2.font, '10px sans-serif', "ctx2.font", "'10px sans-serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.font.weight.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.weight.html
new file mode 100644
index 0000000000..05816b7254
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.font.weight.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.font.weight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.font.weight</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = 'italic 400 12px serif';
+ _assertSame(ctx.font, 'italic 12px serif', "ctx.font", "'italic 12px serif'");
+
+ ctx.font = 'italic 300 12px serif';
+ _assertSame(ctx.font, 'italic 300 12px serif', "ctx.font", "'italic 300 12px serif'");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html
new file mode 100644
index 0000000000..e2cef0d77a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps1</title>
+<h1>2d.text.fontVariantCaps1</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1.html
new file mode 100644
index 0000000000..56acfc61f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps1-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps1</title>
+<h1>2d.text.fontVariantCaps1</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "small-caps";
+ // This should render the same as font = "small-caps 32px serif".
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps2.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps2.html
new file mode 100644
index 0000000000..56efbb6fd3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps2.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.fontVariantCaps2</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Testing small caps setting in fontVariant");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = "small-caps 32px serif";
+ // "mismatch" test, to verify that small-caps does change the rendering.
+ smallCaps_len = ctx.measureText("Hello World").width;
+
+ ctx.font = "32px serif";
+ normalCaps_len = ctx.measureText("Hello World").width;
+ _assert(smallCaps_len != normalCaps_len, "smallCaps_len != normalCaps_len");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html
new file mode 100644
index 0000000000..cf2d5ae119
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps3</title>
+<h1>2d.text.fontVariantCaps3</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("hello world", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3.html
new file mode 100644
index 0000000000..c3d80d3e56
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps3.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps3-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps3</title>
+<h1>2d.text.fontVariantCaps3</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "all-small-caps";
+ // This should render the same as using font = "small-caps 32px serif"
+ // with all the underlying text in lowercase.
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html
new file mode 100644
index 0000000000..3813fd3684
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps4</title>
+<h1>2d.text.fontVariantCaps4</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("hello world", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4.html
new file mode 100644
index 0000000000..1ee9053b4d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps4.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps4-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps4</title>
+<h1>2d.text.fontVariantCaps4</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps overrides the small-caps setting from the font attribute
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html
new file mode 100644
index 0000000000..4bda4ec4b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps5</title>
+<h1>2d.text.fontVariantCaps5</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5.html
new file mode 100644
index 0000000000..d80de4ea31
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps5.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps5-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps5</title>
+<h1>2d.text.fontVariantCaps5</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps 'normal' does not override the setting from the font attribute.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "normal";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html
new file mode 100644
index 0000000000..af9c736aea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps6</title>
+<h1>2d.text.fontVariantCaps6</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6.html
new file mode 100644
index 0000000000..c17fac18b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.fontVariantCaps6.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps6-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps6</title>
+<h1>2d.text.fontVariantCaps6</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ // fontVariantCaps is reset when the font attribute is set.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.actualBoundingBox.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.actualBoundingBox.html
new file mode 100644
index 0000000000..d0672b23dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.actualBoundingBox.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.actualBoundingBox</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.actualBoundingBox</h1>
+<p class="desc">Testing actualBoundingBox</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ ctx.baseline = 'alphabetic'
+ // Different platforms may render text slightly different.
+ // Values that are nominally expected to be zero might actually vary by a
+ // pixel or so if the UA accounts for antialiasing at glyph edges, so we
+ // allow a slight deviation.
+ _assert(Math.abs(ctx.measureText('A').actualBoundingBoxLeft) <= 1, "Math.abs(ctx.measureText('A').actualBoundingBoxLeft) <= 1");
+ _assert(ctx.measureText('A').actualBoundingBoxRight >= 50, "ctx.measureText('A').actualBoundingBoxRight >= 50");
+ _assert(ctx.measureText('A').actualBoundingBoxAscent >= 35, "ctx.measureText('A').actualBoundingBoxAscent >= 35");
+ _assert(Math.abs(ctx.measureText('A').actualBoundingBoxDescent) <= 1, "Math.abs(ctx.measureText('A').actualBoundingBoxDescent) <= 1");
+
+ _assert(ctx.measureText('D').actualBoundingBoxLeft >= 48, "ctx.measureText('D').actualBoundingBoxLeft >= 48");
+ _assert(ctx.measureText('D').actualBoundingBoxLeft <= 52, "ctx.measureText('D').actualBoundingBoxLeft <= 52");
+ _assert(ctx.measureText('D').actualBoundingBoxRight >= 75, "ctx.measureText('D').actualBoundingBoxRight >= 75");
+ _assert(ctx.measureText('D').actualBoundingBoxRight <= 80, "ctx.measureText('D').actualBoundingBoxRight <= 80");
+ _assert(ctx.measureText('D').actualBoundingBoxAscent >= 35, "ctx.measureText('D').actualBoundingBoxAscent >= 35");
+ _assert(ctx.measureText('D').actualBoundingBoxAscent <= 40, "ctx.measureText('D').actualBoundingBoxAscent <= 40");
+ _assert(ctx.measureText('D').actualBoundingBoxDescent >= 12, "ctx.measureText('D').actualBoundingBoxDescent >= 12");
+ _assert(ctx.measureText('D').actualBoundingBoxDescent <= 15, "ctx.measureText('D').actualBoundingBoxDescent <= 15");
+
+ _assert(Math.abs(ctx.measureText('ABCD').actualBoundingBoxLeft) <= 1, "Math.abs(ctx.measureText('ABCD').actualBoundingBoxLeft) <= 1");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxRight >= 200, "ctx.measureText('ABCD').actualBoundingBoxRight >= 200");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxAscent >= 85, "ctx.measureText('ABCD').actualBoundingBoxAscent >= 85");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxDescent >= 37, "ctx.measureText('ABCD').actualBoundingBoxDescent >= 37");
+
+}, "Testing actualBoundingBox");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.advances.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.advances.html
new file mode 100644
index 0000000000..84f04dd677
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.advances.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.advances</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.advances</h1>
+<p class="desc">Testing width advances</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ // Some platforms may return '-0'.
+ _assertSame(Math.abs(ctx.measureText('Hello').advances[0]), 0, "Math.abs(ctx.measureText('Hello').advances[\""+(0)+"\"])", "0");
+ // Different platforms may render text slightly different.
+ _assert(ctx.measureText('Hello').advances[1] >= 36, "ctx.measureText('Hello').advances[\""+(1)+"\"] >= 36");
+ _assert(ctx.measureText('Hello').advances[2] >= 58, "ctx.measureText('Hello').advances[\""+(2)+"\"] >= 58");
+ _assert(ctx.measureText('Hello').advances[3] >= 70, "ctx.measureText('Hello').advances[\""+(3)+"\"] >= 70");
+ _assert(ctx.measureText('Hello').advances[4] >= 80, "ctx.measureText('Hello').advances[\""+(4)+"\"] >= 80");
+
+ var tm = ctx.measureText('Hello');
+ _assertSame(ctx.measureText('Hello').advances[0], tm.advances[0], "ctx.measureText('Hello').advances[\""+(0)+"\"]", "tm.advances[\""+(0)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[1], tm.advances[1], "ctx.measureText('Hello').advances[\""+(1)+"\"]", "tm.advances[\""+(1)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[2], tm.advances[2], "ctx.measureText('Hello').advances[\""+(2)+"\"]", "tm.advances[\""+(2)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[3], tm.advances[3], "ctx.measureText('Hello').advances[\""+(3)+"\"]", "tm.advances[\""+(3)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[4], tm.advances[4], "ctx.measureText('Hello').advances[\""+(4)+"\"]", "tm.advances[\""+(4)+"\"]");
+
+}, "Testing width advances");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.baselines.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.baselines.html
new file mode 100644
index 0000000000..9d947eb361
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.baselines.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.baselines</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.baselines</h1>
+<p class="desc">Testing baselines</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(Math.abs(ctx.measureText('A').alphabeticBaseline), 0, "Math.abs(ctx.measureText('A').alphabeticBaseline)", "0");
+ _assertSame(ctx.measureText('A').ideographicBaseline, 6.25, "ctx.measureText('A').ideographicBaseline", "6.25");
+ _assertSame(ctx.measureText('A').hangingBaseline, 25, "ctx.measureText('A').hangingBaseline", "25");
+
+ _assertSame(Math.abs(ctx.measureText('ABCD').alphabeticBaseline), 0, "Math.abs(ctx.measureText('ABCD').alphabeticBaseline)", "0");
+ _assertSame(ctx.measureText('ABCD').ideographicBaseline, 6.25, "ctx.measureText('ABCD').ideographicBaseline", "6.25");
+ _assertSame(ctx.measureText('ABCD').hangingBaseline, 25, "ctx.measureText('ABCD').hangingBaseline", "25");
+
+}, "Testing baselines");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-low-ascent.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-low-ascent.html
new file mode 100644
index 0000000000..7b6874d10b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-low-ascent.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.emHeights-low-ascent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest-ascent256;
+ src: url("/fonts/CanvasTest-ascent256.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.emHeights-low-ascent</h1>
+<p class="desc">Testing emHeights with reduced ascent metric</p>
+
+
+<span style="font-family: CanvasTest-ascent256; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 20, "ctx.measureText('A').emHeightAscent", "20");
+ _assertSame(ctx.measureText('A').emHeightDescent, 20, "ctx.measureText('A').emHeightDescent", "20");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 20, "ctx.measureText('ABCD').emHeightAscent", "20");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 20, "ctx.measureText('ABCD').emHeightDescent", "20");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+
+}, "Testing emHeights with reduced ascent metric");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-zero-descent.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-zero-descent.html
new file mode 100644
index 0000000000..c3ce994fa1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights-zero-descent.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.emHeights-zero-descent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest-descent0;
+ src: url("/fonts/CanvasTest-descent0.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.emHeights-zero-descent</h1>
+<p class="desc">Testing emHeights with zero descent metric</p>
+
+
+<span style="font-family: CanvasTest-descent0; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightAscent", "40");
+ _assertSame(ctx.measureText('A').emHeightDescent, 0, "ctx.measureText('A').emHeightDescent", "0");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightAscent", "40");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 0, "ctx.measureText('ABCD').emHeightDescent", "0");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+
+}, "Testing emHeights with zero descent metric");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights.html
new file mode 100644
index 0000000000..0db4c30801
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.emHeights.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.emHeights</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.emHeights</h1>
+<p class="desc">Testing emHeights</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 30, "ctx.measureText('A').emHeightAscent", "30");
+ _assertSame(ctx.measureText('A').emHeightDescent, 10, "ctx.measureText('A').emHeightDescent", "10");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 30, "ctx.measureText('ABCD').emHeightAscent", "30");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 10, "ctx.measureText('ABCD').emHeightDescent", "10");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+
+}, "Testing emHeights");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-reduced-ascent.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-reduced-ascent.html
new file mode 100644
index 0000000000..653d26d820
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-reduced-ascent.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.fontBoundingBox-reduced-ascent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest-ascent256;
+ src: url("/fonts/CanvasTest-ascent256.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.fontBoundingBox-reduced-ascent</h1>
+<p class="desc">Testing fontBoundingBox for OffscreenCanvas with reduced ascent metric</p>
+
+
+<span style="font-family: CanvasTest-ascent256; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 10, "ctx.measureText('A').fontBoundingBoxAscent", "10");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 10, "ctx.measureText('ABCD').fontBoundingBoxAscent", "10");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+
+}, "Testing fontBoundingBox for OffscreenCanvas with reduced ascent metric");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-zero-descent.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-zero-descent.html
new file mode 100644
index 0000000000..785c0bc186
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox-zero-descent.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.fontBoundingBox-zero-descent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest-descent0;
+ src: url("/fonts/CanvasTest-descent0.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.fontBoundingBox-zero-descent</h1>
+<p class="desc">Testing fontBoundingBox for OffscreenCanvas with zero descent metric</p>
+
+
+<span style="font-family: CanvasTest-descent0; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 30, "ctx.measureText('A').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 0, "ctx.measureText('A').fontBoundingBoxDescent", "0");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 30, "ctx.measureText('ABCD').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 0, "ctx.measureText('ABCD').fontBoundingBoxDescent", "0");
+
+}, "Testing fontBoundingBox for OffscreenCanvas with zero descent metric");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.ahem.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.ahem.html
new file mode 100644
index 0000000000..0044f4d1e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.ahem.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.fontBoundingBox.ahem</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: Ahem;
+ src: url("/fonts/Ahem.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.fontBoundingBox.ahem</h1>
+<p class="desc">Testing fontBoundingBox for font ahem</p>
+
+
+<span style="font-family: Ahem; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px Ahem';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 40, "ctx.measureText('A').fontBoundingBoxAscent", "40");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 40, "ctx.measureText('ABCD').fontBoundingBoxAscent", "40");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+
+}, "Testing fontBoundingBox for font ahem");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.html
new file mode 100644
index 0000000000..9e7e190754
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.fontBoundingBox.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.fontBoundingBox</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.fontBoundingBox</h1>
+<p class="desc">Testing fontBoundingBox measurements</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 30, "ctx.measureText('A').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 30, "ctx.measureText('ABCD').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+
+}, "Testing fontBoundingBox measurements");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.basic.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.basic.html
new file mode 100644
index 0000000000..36dc468b4e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.basic.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.width.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.width.basic</h1>
+<p class="desc">The width of character is same as font used</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText('A').width, 50, "ctx.measureText('A').width", "50");
+ _assertSame(ctx.measureText('AA').width, 100, "ctx.measureText('AA').width", "100");
+ _assertSame(ctx.measureText('ABCD').width, 200, "ctx.measureText('ABCD').width", "200");
+
+ ctx.font = '100px CanvasTest';
+ _assertSame(ctx.measureText('A').width, 100, "ctx.measureText('A').width", "100");
+
+}, "The width of character is same as font used");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.empty.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.empty.html
new file mode 100644
index 0000000000..39ddad9789
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.empty.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.width.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.width.empty</h1>
+<p class="desc">The empty string has zero width</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText("").width, 0, "ctx.measureText(\"\").width", "0");
+
+}, "The empty string has zero width");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.space.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.space.html
new file mode 100644
index 0000000000..7fd8095e28
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.measure.width.space.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.measure.width.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<style>
+@font-face {
+ font-family: CanvasTest;
+ src: url("/fonts/CanvasTest.ttf");
+}
+</style>
+<body class="show_output">
+
+<h1>2d.text.measure.width.space</h1>
+<p class="desc">Space characters are converted to U+0020 and NOT collapsed</p>
+
+
+<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d');
+
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText('A B').width, 150, "ctx.measureText('A B').width", "150");
+ _assertSame(ctx.measureText('A B').width, 200, "ctx.measureText('A B').width", "200");
+ _assertSame(ctx.measureText('A \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dB').width, 650, "ctx.measureText('A \\x09\\x0a\\x0c\\x0d \\x09\\x0a\\x0c\\x0dB').width", "650");
+ _assert(ctx.measureText('A \x0b B').width >= 200, "ctx.measureText('A \\x0b B').width >= 200");
+
+ _assertSame(ctx.measureText(' AB').width, 150, "ctx.measureText(' AB').width", "150");
+ _assertSame(ctx.measureText('AB ').width, 150, "ctx.measureText('AB ').width", "150");
+
+}, "Space characters are converted to U+0020 and NOT collapsed");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/2d.text.setFont.mathFont.html b/testing/web-platform/tests/html/canvas/element/text/2d.text.setFont.mathFont.html
new file mode 100644
index 0000000000..370104f1b8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/2d.text.setFont.mathFont.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.setFont.mathFont</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.text.setFont.mathFont</h1>
+<p class="desc">crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font");
+_addTest(function(canvas, ctx) {
+
+ ctx.font = "math serif";
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/direction-inherit-rtl.html b/testing/web-platform/tests/html/canvas/element/text/direction-inherit-rtl.html
new file mode 100644
index 0000000000..0ad92181a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/direction-inherit-rtl.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Canvas Test: the 'direction' property</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#text-styles">
+<link rel="match" href="reference/direction-rtl-ref.html">
+<meta name="assert" content="text rendering respects the direction property">
+<style>
+canvas {
+ margin: 10px;
+ border: 1px solid gray;
+}
+</style>
+
+<canvas id="c" width="300" height="300" dir="rtl"></canvas>
+
+<script>
+let ctx = c.getContext("2d");
+ctx.direction = "inherit";
+ctx.font = "16px sans-serif";
+ctx.textAlign = "left";
+ctx.fillText("Hello World!", 150, 50);
+ctx.textAlign = "right";
+ctx.fillText("Hello World!", 150, 100);
+ctx.textAlign = "start";
+ctx.fillText("Hello World!", 150, 150);
+ctx.textAlign = "end";
+ctx.fillText("Hello World!", 150, 200);
+ctx.textAlign = "center";
+ctx.fillText("Hello World!", 150, 250);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/direction-ltr.html b/testing/web-platform/tests/html/canvas/element/text/direction-ltr.html
new file mode 100644
index 0000000000..42a39ac589
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/direction-ltr.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Canvas Test: the 'direction' property</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#text-styles">
+<link rel="match" href="reference/direction-default-ref.html">
+<meta name="assert" content="text rendering respects the direction property">
+<style>
+canvas {
+ margin: 10px;
+ border: 1px solid gray;
+}
+</style>
+
+<canvas id="c" width="300" height="300" dir="rtl"></canvas>
+
+<script>
+let ctx = c.getContext("2d");
+ctx.direction = "ltr";
+ctx.font = "16px sans-serif";
+ctx.textAlign = "left";
+ctx.fillText("Hello World!", 150, 50);
+ctx.textAlign = "right";
+ctx.fillText("Hello World!", 150, 100);
+ctx.textAlign = "start";
+ctx.fillText("Hello World!", 150, 150);
+ctx.textAlign = "end";
+ctx.fillText("Hello World!", 150, 200);
+ctx.textAlign = "center";
+ctx.fillText("Hello World!", 150, 250);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/direction-rtl.html b/testing/web-platform/tests/html/canvas/element/text/direction-rtl.html
new file mode 100644
index 0000000000..3cc67c69f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/direction-rtl.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Canvas Test: the 'direction' property</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#text-styles">
+<link rel="match" href="reference/direction-rtl-ref.html">
+<meta name="assert" content="text rendering respects the direction property">
+<style>
+canvas {
+ margin: 10px;
+ border: 1px solid gray;
+}
+</style>
+
+<canvas id="c" width="300" height="300"></canvas>
+
+<script>
+let ctx = c.getContext("2d");
+ctx.direction = "rtl";
+ctx.font = "16px sans-serif";
+ctx.textAlign = "left";
+ctx.fillText("Hello World!", 150, 50);
+ctx.textAlign = "right";
+ctx.fillText("Hello World!", 150, 100);
+ctx.textAlign = "start";
+ctx.fillText("Hello World!", 150, 150);
+ctx.textAlign = "end";
+ctx.fillText("Hello World!", 150, 200);
+ctx.textAlign = "center";
+ctx.fillText("Hello World!", 150, 250);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/parent-style-relative-units.html b/testing/web-platform/tests/html/canvas/element/text/parent-style-relative-units.html
new file mode 100644
index 0000000000..b9a6b314c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/parent-style-relative-units.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Canvas test: CanvasTextDrawingStyles.font with canvas relative units</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-font">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<canvas id="canvas" style="font-size: 30px; line-height: 40px"></canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext("2d");
+
+ test(() => {
+ ctx.font = "2em serif";
+ assert_equals(ctx.font, "60px serif");
+ }, "Font-size based on canvas element font-size");
+
+ test(() => {
+ // Line-height should be forced to normal, but also irrelevant for resolving
+ // lh-units for font-size.
+ ctx.font = "2lh/100 serif";
+ assert_equals(ctx.font, "80px serif");
+ }, "Font-size based on canvas element line-height");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/text/reference/direction-default-ref.html b/testing/web-platform/tests/html/canvas/element/text/reference/direction-default-ref.html
new file mode 100644
index 0000000000..cef6df259c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/reference/direction-default-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Canvas Reference: the 'direction' property</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<style>
+canvas {
+ margin: 10px;
+ border: 1px solid gray;
+}
+</style>
+
+<canvas id="c" width="300" height="300"></canvas>
+
+<script>
+let ctx = c.getContext("2d");
+ctx.font = "16px sans-serif";
+ctx.textAlign = "left";
+ctx.fillText("Hello World!", 150, 50);
+ctx.textAlign = "right";
+ctx.fillText("Hello World!", 150, 100);
+ctx.textAlign = "start";
+ctx.fillText("Hello World!", 150, 150);
+ctx.textAlign = "end";
+ctx.fillText("Hello World!", 150, 200);
+ctx.textAlign = "center";
+ctx.fillText("Hello World!", 150, 250);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/text/reference/direction-rtl-ref.html b/testing/web-platform/tests/html/canvas/element/text/reference/direction-rtl-ref.html
new file mode 100644
index 0000000000..010526d667
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/text/reference/direction-rtl-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Canvas Reference: the 'direction' property</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<style>
+canvas {
+ margin: 10px;
+ border: 1px solid gray;
+}
+</style>
+
+<canvas id="c" width="300" height="300"></canvas>
+
+<script>
+let ctx = c.getContext("2d");
+ctx.font = "16px sans-serif";
+ctx.textAlign = "left";
+ctx.fillText("!Hello World", 150, 50);
+ctx.textAlign = "right";
+ctx.fillText("!Hello World", 150, 100);
+ctx.textAlign = "right";
+ctx.fillText("!Hello World", 150, 150);
+ctx.textAlign = "left";
+ctx.fillText("!Hello World", 150, 200);
+ctx.textAlign = "center";
+ctx.fillText("!Hello World", 150, 250);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.bitmap.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.bitmap.html
new file mode 100644
index 0000000000..6814679aba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.bitmap.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.bitmap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.bitmap</h1>
+<p class="desc">save()/restore() does not affect the current bitmap</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() does not affect the current bitmap");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.clip.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.clip.html
new file mode 100644
index 0000000000..1ce44ab147
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.clip.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.clip</h1>
+<p class="desc">save()/restore() affects the clipping path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() affects the clipping path");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.fillStyle.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.fillStyle.html
new file mode 100644
index 0000000000..1eb8360e5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.fillStyle.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.fillStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.fillStyle</h1>
+<p class="desc">save()/restore() works for fillStyle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for fillStyle");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.fillStyle;
+ ctx.save();
+ ctx.fillStyle = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.fillStyle, old, "ctx.fillStyle", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.fillStyle = "#ff0000";
+ old = ctx.fillStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.fillStyle, old, "ctx.fillStyle", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.font.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.font.html
new file mode 100644
index 0000000000..8cb4d171bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.font.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.font</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.font</h1>
+<p class="desc">save()/restore() works for font</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for font");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.font;
+ ctx.save();
+ ctx.font = "25px serif";
+ ctx.restore();
+ _assertSame(ctx.font, old, "ctx.font", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.font = "25px serif";
+ old = ctx.font;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "25px serif"
+ ctx.save();
+ _assertSame(ctx.font, old, "ctx.font", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalAlpha.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalAlpha.html
new file mode 100644
index 0000000000..f3dae5ff51
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalAlpha.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.globalAlpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.globalAlpha</h1>
+<p class="desc">save()/restore() works for globalAlpha</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for globalAlpha");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalAlpha;
+ ctx.save();
+ ctx.globalAlpha = 0.5;
+ ctx.restore();
+ _assertSame(ctx.globalAlpha, old, "ctx.globalAlpha", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.globalAlpha = 0.5;
+ old = ctx.globalAlpha;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.globalAlpha, old, "ctx.globalAlpha", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html
new file mode 100644
index 0000000000..fed0ceec3b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.globalCompositeOperation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.globalCompositeOperation</h1>
+<p class="desc">save()/restore() works for globalCompositeOperation</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for globalCompositeOperation");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalCompositeOperation;
+ ctx.save();
+ ctx.globalCompositeOperation = "copy";
+ ctx.restore();
+ _assertSame(ctx.globalCompositeOperation, old, "ctx.globalCompositeOperation", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.globalCompositeOperation = "copy";
+ old = ctx.globalCompositeOperation;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "copy"
+ ctx.save();
+ _assertSame(ctx.globalCompositeOperation, old, "ctx.globalCompositeOperation", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineCap.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineCap.html
new file mode 100644
index 0000000000..90c52ce564
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineCap.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.lineCap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.lineCap</h1>
+<p class="desc">save()/restore() works for lineCap</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for lineCap");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineCap;
+ ctx.save();
+ ctx.lineCap = "round";
+ ctx.restore();
+ _assertSame(ctx.lineCap, old, "ctx.lineCap", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineCap = "round";
+ old = ctx.lineCap;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ _assertSame(ctx.lineCap, old, "ctx.lineCap", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineJoin.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineJoin.html
new file mode 100644
index 0000000000..00495d9fb6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineJoin.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.lineJoin</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.lineJoin</h1>
+<p class="desc">save()/restore() works for lineJoin</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for lineJoin");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineJoin;
+ ctx.save();
+ ctx.lineJoin = "round";
+ ctx.restore();
+ _assertSame(ctx.lineJoin, old, "ctx.lineJoin", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineJoin = "round";
+ old = ctx.lineJoin;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ _assertSame(ctx.lineJoin, old, "ctx.lineJoin", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineWidth.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineWidth.html
new file mode 100644
index 0000000000..0705878d0a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.lineWidth.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.lineWidth</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.lineWidth</h1>
+<p class="desc">save()/restore() works for lineWidth</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for lineWidth");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineWidth;
+ ctx.save();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ _assertSame(ctx.lineWidth, old, "ctx.lineWidth", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineWidth = 0.5;
+ old = ctx.lineWidth;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.lineWidth, old, "ctx.lineWidth", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.miterLimit.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.miterLimit.html
new file mode 100644
index 0000000000..efd2207515
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.miterLimit.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.miterLimit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.miterLimit</h1>
+<p class="desc">save()/restore() works for miterLimit</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for miterLimit");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.miterLimit;
+ ctx.save();
+ ctx.miterLimit = 0.5;
+ ctx.restore();
+ _assertSame(ctx.miterLimit, old, "ctx.miterLimit", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.miterLimit = 0.5;
+ old = ctx.miterLimit;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.miterLimit, old, "ctx.miterLimit", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.path.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.path.html
new file mode 100644
index 0000000000..5848ae560c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.path.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.path</h1>
+<p class="desc">save()/restore() does not affect the current path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() does not affect the current path");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 100, 50);
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowBlur.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowBlur.html
new file mode 100644
index 0000000000..c5699b78fd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowBlur.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.shadowBlur</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.shadowBlur</h1>
+<p class="desc">save()/restore() works for shadowBlur</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for shadowBlur");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowBlur;
+ ctx.save();
+ ctx.shadowBlur = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowBlur, old, "ctx.shadowBlur", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowBlur = 5;
+ old = ctx.shadowBlur;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowBlur, old, "ctx.shadowBlur", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowColor.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowColor.html
new file mode 100644
index 0000000000..9b6a435202
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowColor.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.shadowColor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.shadowColor</h1>
+<p class="desc">save()/restore() works for shadowColor</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for shadowColor");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowColor;
+ ctx.save();
+ ctx.shadowColor = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.shadowColor, old, "ctx.shadowColor", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowColor = "#ff0000";
+ old = ctx.shadowColor;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.shadowColor, old, "ctx.shadowColor", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetX.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetX.html
new file mode 100644
index 0000000000..427a44a373
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetX.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.shadowOffsetX</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.shadowOffsetX</h1>
+<p class="desc">save()/restore() works for shadowOffsetX</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for shadowOffsetX");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetX;
+ ctx.save();
+ ctx.shadowOffsetX = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowOffsetX, old, "ctx.shadowOffsetX", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetX = 5;
+ old = ctx.shadowOffsetX;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowOffsetX, old, "ctx.shadowOffsetX", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetY.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetY.html
new file mode 100644
index 0000000000..b711445c20
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.shadowOffsetY.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.shadowOffsetY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.shadowOffsetY</h1>
+<p class="desc">save()/restore() works for shadowOffsetY</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for shadowOffsetY");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetY;
+ ctx.save();
+ ctx.shadowOffsetY = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowOffsetY, old, "ctx.shadowOffsetY", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetY = 5;
+ old = ctx.shadowOffsetY;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowOffsetY, old, "ctx.shadowOffsetY", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stack.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stack.html
new file mode 100644
index 0000000000..122c543473
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stack.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.stack</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.stack</h1>
+<p class="desc">save()/restore() can be nested as a stack</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() can be nested as a stack");
+_addTest(function(canvas, ctx) {
+
+ ctx.lineWidth = 1;
+ ctx.save();
+ ctx.lineWidth = 2;
+ ctx.save();
+ ctx.lineWidth = 3;
+ _assertSame(ctx.lineWidth, 3, "ctx.lineWidth", "3");
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 2, "ctx.lineWidth", "2");
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stackdepth.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stackdepth.html
new file mode 100644
index 0000000000..6fa591d06a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.stackdepth.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.stackdepth</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.stackdepth</h1>
+<p class="desc">save()/restore() stack depth is not unreasonably limited</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() stack depth is not unreasonably limited");
+_addTest(function(canvas, ctx) {
+
+ var limit = 512;
+ for (var i = 1; i < limit; ++i)
+ {
+ ctx.save();
+ ctx.lineWidth = i;
+ }
+ for (var i = limit-1; i > 0; --i)
+ {
+ _assertSame(ctx.lineWidth, i, "ctx.lineWidth", "i");
+ ctx.restore();
+ }
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.strokeStyle.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.strokeStyle.html
new file mode 100644
index 0000000000..9ccaac7e7a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.strokeStyle.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.strokeStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.strokeStyle</h1>
+<p class="desc">save()/restore() works for strokeStyle</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for strokeStyle");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.strokeStyle;
+ ctx.save();
+ ctx.strokeStyle = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.strokeStyle, old, "ctx.strokeStyle", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.strokeStyle = "#ff0000";
+ old = ctx.strokeStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.strokeStyle, old, "ctx.strokeStyle", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textAlign.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textAlign.html
new file mode 100644
index 0000000000..a86d62a8b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textAlign.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.textAlign</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.textAlign</h1>
+<p class="desc">save()/restore() works for textAlign</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for textAlign");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.textAlign;
+ ctx.save();
+ ctx.textAlign = "center";
+ ctx.restore();
+ _assertSame(ctx.textAlign, old, "ctx.textAlign", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.textAlign = "center";
+ old = ctx.textAlign;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "center"
+ ctx.save();
+ _assertSame(ctx.textAlign, old, "ctx.textAlign", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textBaseline.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textBaseline.html
new file mode 100644
index 0000000000..5cbf712fb1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.textBaseline.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.textBaseline</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.textBaseline</h1>
+<p class="desc">save()/restore() works for textBaseline</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() works for textBaseline");
+_addTest(function(canvas, ctx) {
+
+ // Test that restore() undoes any modifications
+ var old = ctx.textBaseline;
+ ctx.save();
+ ctx.textBaseline = "bottom";
+ ctx.restore();
+ _assertSame(ctx.textBaseline, old, "ctx.textBaseline", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.textBaseline = "bottom";
+ old = ctx.textBaseline;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "bottom"
+ ctx.save();
+ _assertSame(ctx.textBaseline, old, "ctx.textBaseline", "old");
+ ctx.restore();
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.transformation.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.transformation.html
new file mode 100644
index 0000000000..6edee8ae84
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.transformation.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.transformation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.transformation</h1>
+<p class="desc">save()/restore() affects the current transformation matrix</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("save()/restore() affects the current transformation matrix");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.translate(200, 0);
+ ctx.restore();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(-200, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.underflow.html b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.underflow.html
new file mode 100644
index 0000000000..763f269556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/the-canvas-state/2d.state.saverestore.underflow.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.state.saverestore.underflow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.state.saverestore.underflow</h1>
+<p class="desc">restore() with an empty stack has no effect</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("restore() with an empty stack has no effect");
+_addTest(function(canvas, ctx) {
+
+ for (var i = 0; i < 16; ++i)
+ ctx.restore();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 0.5, "ctx.lineWidth", "0.5");
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.order.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.order.html
new file mode 100644
index 0000000000..6c97bf7426
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.order.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.order</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.order</h1>
+<p class="desc">Transformations are applied in the right order</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Transformations are applied in the right order");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 1);
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -50, 50, 50);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.direction.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.direction.html
new file mode 100644
index 0000000000..0b583cd678
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.direction.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.rotate.direction</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.rotate.direction</h1>
+<p class="desc">rotate() is clockwise</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("rotate() is clockwise");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -100, 50, 100);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.nonfinite.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.nonfinite.html
new file mode 100644
index 0000000000..3e685fa7a8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.nonfinite.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.rotate.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.rotate.nonfinite</h1>
+<p class="desc">rotate() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("rotate() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.rotate(Infinity);
+ ctx.rotate(-Infinity);
+ ctx.rotate(NaN);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.radians.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.radians.html
new file mode 100644
index 0000000000..63f895a0de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.radians.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.rotate.radians</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.rotate.radians</h1>
+<p class="desc">rotate() uses radians</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("rotate() uses radians");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrap.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrap.html
new file mode 100644
index 0000000000..9b923e0008
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrap.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.rotate.wrap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.rotate.wrap</h1>
+<p class="desc">rotate() wraps large positive values correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("rotate() wraps large positive values correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi)
+ // We need about pi +/- 0.001 in order to get correct-looking results
+ // 32-bit floats can store pi*4097 with precision 2^-10, so that should
+ // be safe enough on reasonable implementations
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,2, 0,255,0,255);
+ _assertPixel(canvas, 98,47, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrapnegative.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrapnegative.html
new file mode 100644
index 0000000000..96894ef20e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.wrapnegative.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.rotate.wrapnegative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.rotate.wrapnegative</h1>
+<p class="desc">rotate() wraps large negative values correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("rotate() wraps large negative values correctly");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(-Math.PI * (1 + 4096));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,2, 0,255,0,255);
+ _assertPixel(canvas, 98,47, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.zero.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.zero.html
new file mode 100644
index 0000000000..7026ea9d1b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.rotate.zero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.rotate.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.rotate.zero</h1>
+<p class="desc">rotate() by 0 does nothing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("rotate() by 0 does nothing");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.basic.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.basic.html
new file mode 100644
index 0000000000..7e4b3593b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.basic.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.scale.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.scale.basic</h1>
+<p class="desc">scale() works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("scale() works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 4);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 12.5);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.large.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.large.html
new file mode 100644
index 0000000000..ce7f6d9fae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.large.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.scale.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.scale.large</h1>
+<p class="desc">scale() with large scale factors works</p>
+
+<p class="notes">Not really that large at all, but it hits the limits in Firefox.
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("scale() with large scale factors works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(1e5, 1e5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 1, 1);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.multiple.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.multiple.html
new file mode 100644
index 0000000000..73bfbc87c1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.multiple.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.scale.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.scale.multiple</h1>
+<p class="desc">Multiple scale()s combine</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Multiple scale()s combine");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.negative.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.negative.html
new file mode 100644
index 0000000000..a5aef69b63
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.negative.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.scale.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.scale.negative</h1>
+<p class="desc">scale() with negative scale factors works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("scale() with negative scale factors works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.scale(-1, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.scale(1, -1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, -50, 50, 50);
+ ctx.restore();
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.nonfinite.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.nonfinite.html
new file mode 100644
index 0000000000..c06f96eb22
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.nonfinite.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.scale.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.scale.nonfinite</h1>
+<p class="desc">scale() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("scale() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.scale(Infinity, 0.1);
+ ctx.scale(-Infinity, 0.1);
+ ctx.scale(NaN, 0.1);
+ ctx.scale(0.1, Infinity);
+ ctx.scale(0.1, -Infinity);
+ ctx.scale(0.1, NaN);
+ ctx.scale(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.zero.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.zero.html
new file mode 100644
index 0000000000..ae15034a19
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.scale.zero.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.scale.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.scale.zero</h1>
+<p class="desc">scale() with a scale factor of zero works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("scale() with a scale factor of zero works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.scale(0, 1);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.translate(0, 25);
+ ctx.scale(1, 0);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.multiple.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.multiple.html
new file mode 100644
index 0000000000..099831e638
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.multiple.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.setTransform.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.setTransform.multiple</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.setTransform(1/2,0, 0,1/2, 0,0);
+ ctx.setTransform();
+ ctx.setTransform(2,0, 0,2, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ _assertPixel(canvas, 75,35, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.nonfinite.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.nonfinite.html
new file mode 100644
index 0000000000..019493ad16
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.nonfinite.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.setTransform.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.setTransform.nonfinite</h1>
+<p class="desc">setTransform() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("setTransform() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(NaN, 0, 0, 0, 0, 0);
+ ctx.setTransform(0, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, -Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, NaN, 0, 0, 0, 0);
+ ctx.setTransform(0, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, -Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, NaN, 0, 0, 0);
+ ctx.setTransform(0, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, -Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, NaN, 0, 0);
+ ctx.setTransform(0, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, -Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, NaN, 0);
+ ctx.setTransform(0, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, -Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, NaN);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.skewed.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.skewed.html
new file mode 100644
index 0000000000..f6f8655b1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.setTransform.skewed.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.setTransform.skewed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.setTransform.skewed</h1>
+<p class="desc"></p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.setTransform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ _assertPixel(canvas, 21,11, 0,255,0,255);
+ _assertPixel(canvas, 79,11, 0,255,0,255);
+ _assertPixel(canvas, 21,39, 0,255,0,255);
+ _assertPixel(canvas, 79,39, 0,255,0,255);
+ _assertPixel(canvas, 39,19, 0,255,0,255);
+ _assertPixel(canvas, 61,19, 0,255,0,255);
+ _assertPixel(canvas, 39,31, 0,255,0,255);
+ _assertPixel(canvas, 61,31, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.identity.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.identity.html
new file mode 100644
index 0000000000..be5de19a45
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.identity.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.transform.identity</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.transform.identity</h1>
+<p class="desc">transform() with the identity matrix does nothing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("transform() with the identity matrix does nothing");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,0, 0,1, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.multiply.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.multiply.html
new file mode 100644
index 0000000000..1e8e4cccdf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.multiply.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.transform.multiply</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.transform.multiply</h1>
+<p class="desc">transform() multiplies the CTM</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("transform() multiplies the CTM");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,2, 3,4, 5,6);
+ ctx.transform(-2,1, 3/2,-1/2, 1,-2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.nonfinite.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.nonfinite.html
new file mode 100644
index 0000000000..d3fae8520c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.nonfinite.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.transform.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.transform.nonfinite</h1>
+<p class="desc">transform() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("transform() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.transform(Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(NaN, 0, 0, 0, 0, 0);
+ ctx.transform(0, Infinity, 0, 0, 0, 0);
+ ctx.transform(0, -Infinity, 0, 0, 0, 0);
+ ctx.transform(0, NaN, 0, 0, 0, 0);
+ ctx.transform(0, 0, Infinity, 0, 0, 0);
+ ctx.transform(0, 0, -Infinity, 0, 0, 0);
+ ctx.transform(0, 0, NaN, 0, 0, 0);
+ ctx.transform(0, 0, 0, Infinity, 0, 0);
+ ctx.transform(0, 0, 0, -Infinity, 0, 0);
+ ctx.transform(0, 0, 0, NaN, 0, 0);
+ ctx.transform(0, 0, 0, 0, Infinity, 0);
+ ctx.transform(0, 0, 0, 0, -Infinity, 0);
+ ctx.transform(0, 0, 0, 0, NaN, 0);
+ ctx.transform(0, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, 0, -Infinity);
+ ctx.transform(0, 0, 0, 0, 0, NaN);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.skewed.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.skewed.html
new file mode 100644
index 0000000000..c69756bc1d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.transform.skewed.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.transform.skewed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.transform.skewed</h1>
+<p class="desc">transform() with skewy matrix transforms correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("transform() with skewy matrix transforms correctly");
+_addTest(function(canvas, ctx) {
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.transform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ _assertPixel(canvas, 21,11, 0,255,0,255);
+ _assertPixel(canvas, 79,11, 0,255,0,255);
+ _assertPixel(canvas, 21,39, 0,255,0,255);
+ _assertPixel(canvas, 79,39, 0,255,0,255);
+ _assertPixel(canvas, 39,19, 0,255,0,255);
+ _assertPixel(canvas, 61,19, 0,255,0,255);
+ _assertPixel(canvas, 39,31, 0,255,0,255);
+ _assertPixel(canvas, 61,31, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.basic.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.basic.html
new file mode 100644
index 0000000000..189a1544b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.basic.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.translate.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.translate.basic</h1>
+<p class="desc">translate() works</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("translate() works");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.nonfinite.html b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.nonfinite.html
new file mode 100644
index 0000000000..0857693aff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/transformations/2d.transformation.translate.nonfinite.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.transformation.translate.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.transformation.translate.nonfinite</h1>
+<p class="desc">translate() with Infinity/NaN is ignored</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("translate() with Infinity/NaN is ignored");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.translate(Infinity, 0.1);
+ ctx.translate(-Infinity, 0.1);
+ ctx.translate(NaN, 0.1);
+ ctx.translate(0.1, Infinity);
+ ctx.translate(0.1, -Infinity);
+ ctx.translate(0.1, NaN);
+ ctx.translate(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/video/2d.video.invalid.html b/testing/web-platform/tests/html/canvas/element/video/2d.video.invalid.html
new file mode 100644
index 0000000000..22b4e054f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/video/2d.video.invalid.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.video.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.video.invalid</h1>
+<p class="desc">Verify test doesn't crash with invalid video.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Verify test doesn't crash with invalid video.");
+_addTest(function(canvas, ctx) {
+
+ var v = document.createElement('video');
+ v.play();
+ // Test is deliberately not waiting for the 'playing' event to fire.
+ ctx.createPattern(v, 'repeat-x');
+ ctx.drawImage(v, 0, 0);
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.html
new file mode 100644
index 0000000000..9c3d1b3374
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.fillText</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.fillText</h1>
+<p class="desc">Test if fillText can be used with a solid display-p3 color</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test if fillText can be used with a solid display-p3 color");
+_addTest(function(canvas, ctx) {
+
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.fillStyle = "#f00";
+ ctx.fillText("A", 0, 50);
+
+ ctx.fillStyle = "black";
+ ctx.fillStyle = "color(display-p3 100% 0 0)";
+ ctx.fillText("A", 50, 50);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.shadow.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.shadow.html
new file mode 100644
index 0000000000..cc459fb2cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.fillText.shadow.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.fillText.shadow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.fillText.shadow</h1>
+<p class="desc">Test if fillText can be used with a display-p3 shadow color</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test if fillText can be used with a display-p3 shadow color");
+_addTest(function(canvas, ctx) {
+
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.fillStyle = "black";
+ ctx.shadowBlur = 4;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = "#f00";
+ ctx.fillText("A", 0, 0);
+
+ ctx.shadowColor = "black";
+ ctx.shadowColor = "color(display-p3 100% 0 0)";
+ ctx.fillText("A", 50, 0);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.strokeText.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.strokeText.html
new file mode 100644
index 0000000000..626a41b49b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.strokeText.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.strokeText</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.strokeText</h1>
+<p class="desc">Test if strokeText can be used with a solid display-p3 color</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Test if strokeText can be used with a solid display-p3 color");
+_addTest(function(canvas, ctx) {
+
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.strokeStyle = "#f00";
+ ctx.lineWidth = 20;
+ ctx.strokeText("A", 0, 50);
+
+ ctx.strokeStyle = "black";
+ ctx.strokeStyle = "color(display-p3 100% 0 0)";
+ ctx.strokeText("A", 50, 50);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3.html
new file mode 100644
index 0000000000..a03f49740f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.p3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.to.p3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.to.p3</h1>
+<p class="desc">test getImageData with display-p3 and uint8 from display p3 uint8 canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test getImageData with display-p3 and uint8 from display p3 uint8 canvas");
+_addTest(function(canvas, ctx) {
+
+ var color_style = 'rgb(50, 100, 150)';
+ // [0.24304, 0.38818, 0.57227, 1.0] * 255 = [62, 99, 146, 255]
+ var pixel_expected = [62, 99, 146, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "display-p3", storageFormat: "uint8"}).data;
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.srgb.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.srgb.html
new file mode 100644
index 0000000000..0433ae38c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.to.srgb.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.to.srgb</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.to.srgb</h1>
+<p class="desc">test getImageData with srsb and uint8 from display p3 uint8 canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test getImageData with srsb and uint8 from display p3 uint8 canvas");
+_addTest(function(canvas, ctx) {
+
+ var color_style = 'rgb(50, 100, 150)';
+ var pixel_expected = [50, 100, 150, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "srgb", storageFormat: "uint8"}).data;
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.p3.canvas.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.p3.canvas.html
new file mode 100644
index 0000000000..1a44af20a6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.p3.canvas.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.toBlob.p3.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.toBlob.p3.canvas</h1>
+<p class="desc">test if toblob returns p3 data from p3 color space canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test if toblob returns p3 data from p3 color space canvas");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+
+ canvas.toBlob(function(blob) {
+ var urlCreator = window.URL || window.webkitURL;
+ image.src = urlCreator.createObjectURL(blob);
+ }, 'image/png', 1);
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.with.putImageData.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.with.putImageData.html
new file mode 100644
index 0000000000..a53de72259
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toBlob.with.putImageData.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.toBlob.with.putImageData</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.toBlob.with.putImageData</h1>
+<p class="desc">Use putImageData to put some p3 data in canvas and test if toBlob returns the same data</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Use putImageData to put some p3 data in canvas and test if toBlob returns the same data");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 2;
+ canvas.height = 2;
+
+ // Create an ImageData using createImageData and populate its data array.
+ var image_data = ctx.createImageData(canvas.width, canvas.height, {colorSpace: "display-p3"});
+ var color_data = [[255, 100, 150, 1.0], [255, 100, 150, 0.5],
+ [255, 100, 150, 0.5], [255, 100, 150, 0]];
+ var data = image_data.data;
+ for (var i = 0; i < data.length / 4; ++i) {
+ data[4*i + 0] = color_data[i][0];
+ data[4*i + 1] = color_data[i][1];
+ data[4*i + 2] = color_data[i][2];
+ data[4*i + 3] = color_data[i][3];
+ }
+ ctx.putImageData(image_data, 0, 0);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ canvas.toBlob(function(blob) {
+ var urlCreator = window.URL || window.webkitURL;
+ image.src = urlCreator.createObjectURL(blob);
+ }, 'image/png', 1);
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.jpeg.p3.canvas.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.jpeg.p3.canvas.html
new file mode 100644
index 0000000000..e0986cb8e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.jpeg.p3.canvas.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.toDataURL.jpeg.p3.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.toDataURL.jpeg.p3.canvas</h1>
+<p class="desc">test if toDataURL('image/jpeg') returns p3 data from canvas with p3 color space</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test if toDataURL('image/jpeg') returns p3 data from canvas with p3 color space");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL("image/jpeg");
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.p3.canvas.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.p3.canvas.html
new file mode 100644
index 0000000000..94ba703980
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.p3.canvas.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.toDataURL.p3.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.toDataURL.p3.canvas</h1>
+<p class="desc">test if toDataURL returns p3 data from canvas with p3 color space</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("test if toDataURL returns p3 data from canvas with p3 color space");
+_addTest(function(canvas, ctx) {
+
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL();
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.with.putImageData.html b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.with.putImageData.html
new file mode 100644
index 0000000000..58d0718eba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/element/wide-gamut-canvas/2d.color.space.p3.toDataURL.with.putImageData.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.color.space.p3.toDataURL.with.putImageData</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.color.space.p3.toDataURL.with.putImageData</h1>
+<p class="desc">Use putImageData to put some p3 data in canvas and test if toDataURL returns the same data</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Use putImageData to put some p3 data in canvas and test if toDataURL returns the same data");
+_addTest(function(canvas, ctx) {
+
+ canvas.width = 2;
+ canvas.height = 2;
+
+ // Create an ImageData using createImageData and populate its data array.
+ var image_data = ctx.createImageData(canvas.width, canvas.height, {colorSpace: "display-p3"});
+ var color_data = [[255, 100, 150, 1.0], [255, 100, 150, 0.5],
+ [255, 100, 150, 0.5], [255, 100, 150, 0]];
+ var data = image_data.data;
+ for (var i = 0; i < data.length / 4; ++i) {
+ data[4*i + 0] = color_data[i][0];
+ data[4*i + 1] = color_data[i][1];
+ data[4*i + 2] = color_data[i][2];
+ data[4*i + 3] = color_data[i][3];
+ }
+ ctx.putImageData(image_data, 0, 0);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL();
+
+}, {colorSpace: "display-p3"});
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.html b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.html
new file mode 100644
index 0000000000..a89ec10f9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.conformance.requirements.basics</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.conformance.requirements.basics</h1>
+<p class="desc">void methods return undefined</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("void methods return undefined");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+var canvas = new OffscreenCanvas(100, 50);
+var ctx = canvas.getContext('2d');
+
+_assertSame(ctx.save(), undefined, "ctx.save()", "undefined");
+_assertSame(ctx.restore(), undefined, "ctx.restore()", "undefined");
+_assertSame(ctx.scale(1, 1), undefined, "ctx.scale(1, 1)", "undefined");
+_assertSame(ctx.rotate(0), undefined, "ctx.rotate(0)", "undefined");
+_assertSame(ctx.translate(0, 0), undefined, "ctx.translate(0, 0)", "undefined");
+if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ _assertSame(ctx.transform(1, 0, 0, 1, 0, 0), undefined, "ctx.transform(1, 0, 0, 1, 0, 0)", "undefined");
+}
+if (ctx.setTransform) {
+ _assertSame(ctx.setTransform(1, 0, 0, 1, 0, 0), undefined, "ctx.setTransform(1, 0, 0, 1, 0, 0)", "undefined");
+ _assertSame(ctx.setTransform(), undefined, "ctx.setTransform()", "undefined");
+}
+_assertSame(ctx.clearRect(0, 0, 0, 0), undefined, "ctx.clearRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.fillRect(0, 0, 0, 0), undefined, "ctx.fillRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.strokeRect(0, 0, 0, 0), undefined, "ctx.strokeRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.beginPath(), undefined, "ctx.beginPath()", "undefined");
+_assertSame(ctx.closePath(), undefined, "ctx.closePath()", "undefined");
+_assertSame(ctx.moveTo(0, 0), undefined, "ctx.moveTo(0, 0)", "undefined");
+_assertSame(ctx.lineTo(0, 0), undefined, "ctx.lineTo(0, 0)", "undefined");
+_assertSame(ctx.quadraticCurveTo(0, 0, 0, 0), undefined, "ctx.quadraticCurveTo(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.bezierCurveTo(0, 0, 0, 0, 0, 0), undefined, "ctx.bezierCurveTo(0, 0, 0, 0, 0, 0)", "undefined");
+_assertSame(ctx.arcTo(0, 0, 0, 0, 1), undefined, "ctx.arcTo(0, 0, 0, 0, 1)", "undefined");
+_assertSame(ctx.rect(0, 0, 0, 0), undefined, "ctx.rect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.arc(0, 0, 1, 0, 0, true), undefined, "ctx.arc(0, 0, 1, 0, 0, true)", "undefined");
+_assertSame(ctx.fill(), undefined, "ctx.fill()", "undefined");
+_assertSame(ctx.stroke(), undefined, "ctx.stroke()", "undefined");
+_assertSame(ctx.clip(), undefined, "ctx.clip()", "undefined");
+if (ctx.fillText) {
+ _assertSame(ctx.fillText('test', 0, 0), undefined, "ctx.fillText('test', 0, 0)", "undefined");
+ _assertSame(ctx.strokeText('test', 0, 0), undefined, "ctx.strokeText('test', 0, 0)", "undefined");
+}
+if (ctx.putImageData) {
+ _assertSame(ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0), undefined, "ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0)", "undefined");
+}
+_assertSame(ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+_assertSame(ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white'), undefined, "ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white')", "undefined");
+t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.worker.js b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.worker.js
new file mode 100644
index 0000000000..8d6ddc894f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.basics.worker.js
@@ -0,0 +1,58 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.conformance.requirements.basics
+// Description:void methods return undefined
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("void methods return undefined");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+var canvas = new OffscreenCanvas(100, 50);
+var ctx = canvas.getContext('2d');
+
+_assertSame(ctx.save(), undefined, "ctx.save()", "undefined");
+_assertSame(ctx.restore(), undefined, "ctx.restore()", "undefined");
+_assertSame(ctx.scale(1, 1), undefined, "ctx.scale(1, 1)", "undefined");
+_assertSame(ctx.rotate(0), undefined, "ctx.rotate(0)", "undefined");
+_assertSame(ctx.translate(0, 0), undefined, "ctx.translate(0, 0)", "undefined");
+if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ _assertSame(ctx.transform(1, 0, 0, 1, 0, 0), undefined, "ctx.transform(1, 0, 0, 1, 0, 0)", "undefined");
+}
+if (ctx.setTransform) {
+ _assertSame(ctx.setTransform(1, 0, 0, 1, 0, 0), undefined, "ctx.setTransform(1, 0, 0, 1, 0, 0)", "undefined");
+ _assertSame(ctx.setTransform(), undefined, "ctx.setTransform()", "undefined");
+}
+_assertSame(ctx.clearRect(0, 0, 0, 0), undefined, "ctx.clearRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.fillRect(0, 0, 0, 0), undefined, "ctx.fillRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.strokeRect(0, 0, 0, 0), undefined, "ctx.strokeRect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.beginPath(), undefined, "ctx.beginPath()", "undefined");
+_assertSame(ctx.closePath(), undefined, "ctx.closePath()", "undefined");
+_assertSame(ctx.moveTo(0, 0), undefined, "ctx.moveTo(0, 0)", "undefined");
+_assertSame(ctx.lineTo(0, 0), undefined, "ctx.lineTo(0, 0)", "undefined");
+_assertSame(ctx.quadraticCurveTo(0, 0, 0, 0), undefined, "ctx.quadraticCurveTo(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.bezierCurveTo(0, 0, 0, 0, 0, 0), undefined, "ctx.bezierCurveTo(0, 0, 0, 0, 0, 0)", "undefined");
+_assertSame(ctx.arcTo(0, 0, 0, 0, 1), undefined, "ctx.arcTo(0, 0, 0, 0, 1)", "undefined");
+_assertSame(ctx.rect(0, 0, 0, 0), undefined, "ctx.rect(0, 0, 0, 0)", "undefined");
+_assertSame(ctx.arc(0, 0, 1, 0, 0, true), undefined, "ctx.arc(0, 0, 1, 0, 0, true)", "undefined");
+_assertSame(ctx.fill(), undefined, "ctx.fill()", "undefined");
+_assertSame(ctx.stroke(), undefined, "ctx.stroke()", "undefined");
+_assertSame(ctx.clip(), undefined, "ctx.clip()", "undefined");
+if (ctx.fillText) {
+ _assertSame(ctx.fillText('test', 0, 0), undefined, "ctx.fillText('test', 0, 0)", "undefined");
+ _assertSame(ctx.strokeText('test', 0, 0), undefined, "ctx.strokeText('test', 0, 0)", "undefined");
+}
+if (ctx.putImageData) {
+ _assertSame(ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0), undefined, "ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0)", "undefined");
+}
+_assertSame(ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+_assertSame(ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white'), undefined, "ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white')", "undefined");
+t.done();
+
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.html b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.html
new file mode 100644
index 0000000000..cfbbca9e5e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.conformance.requirements.missingargs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.conformance.requirements.missingargs</h1>
+<p class="desc">Missing arguments cause TypeError</p>
+
+
+<script>
+var t = async_test("Missing arguments cause TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+var canvas = new OffscreenCanvas(100, 50);
+var ctx = canvas.getContext('2d');
+
+assert_throws_js(TypeError, function() { ctx.scale(); });
+assert_throws_js(TypeError, function() { ctx.scale(1); });
+assert_throws_js(TypeError, function() { ctx.rotate(); });
+assert_throws_js(TypeError, function() { ctx.translate(); });
+assert_throws_js(TypeError, function() { ctx.translate(0); });
+if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ assert_throws_js(TypeError, function() { ctx.transform(); });
+ assert_throws_js(TypeError, function() { ctx.transform(1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1, 0); });
+}
+if (ctx.setTransform) {
+ assert_throws_js(TypeError, function() { ctx.setTransform(1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1, 0); });
+}
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.createPattern(canvas); });
+assert_throws_js(TypeError, function() { ctx.clearRect(); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.moveTo(); });
+assert_throws_js(TypeError, function() { ctx.moveTo(0); });
+assert_throws_js(TypeError, function() { ctx.lineTo(); });
+assert_throws_js(TypeError, function() { ctx.lineTo(0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.rect(); });
+assert_throws_js(TypeError, function() { ctx.rect(0); });
+assert_throws_js(TypeError, function() { ctx.rect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.rect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arc(); });
+assert_throws_js(TypeError, function() { ctx.arc(0); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1, 0); });
+// (6th argument to arc is optional)
+if (ctx.isPointInPath) {
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(0); });
+}
+if (ctx.drawFocusRing) {
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas, 0); });
+}
+if (ctx.fillText) {
+ assert_throws_js(TypeError, function() { ctx.fillText(); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test'); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeText(); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test'); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.measureText(); });
+}
+assert_throws_js(TypeError, function() { ctx.drawImage(); });
+assert_throws_js(TypeError, function() { ctx.drawImage(canvas); });
+assert_throws_js(TypeError, function() { ctx.drawImage(canvas, 0); });
+// TODO: n >= 3 args on drawImage could be either a valid overload,
+// or too few for another overload, or too many for another
+// overload - what should happen?
+if (ctx.createImageData) {
+ assert_throws_js(TypeError, function() { ctx.createImageData(); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(1); });
+}
+if (ctx.getImageData) {
+ assert_throws_js(TypeError, function() { ctx.getImageData(); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0, 1); });
+}
+if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ assert_throws_js(TypeError, function() { ctx.putImageData(); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0); });
+}
+var g = ctx.createLinearGradient(0, 0, 0, 0);
+assert_throws_js(TypeError, function() { g.addColorStop(); });
+assert_throws_js(TypeError, function() { g.addColorStop(0); });
+t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.worker.js b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.worker.js
new file mode 100644
index 0000000000..fe1b111f05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/2d.conformance.requirements.missingargs.worker.js
@@ -0,0 +1,137 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.conformance.requirements.missingargs
+// Description:Missing arguments cause TypeError
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Missing arguments cause TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+var canvas = new OffscreenCanvas(100, 50);
+var ctx = canvas.getContext('2d');
+
+assert_throws_js(TypeError, function() { ctx.scale(); });
+assert_throws_js(TypeError, function() { ctx.scale(1); });
+assert_throws_js(TypeError, function() { ctx.rotate(); });
+assert_throws_js(TypeError, function() { ctx.translate(); });
+assert_throws_js(TypeError, function() { ctx.translate(0); });
+if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ assert_throws_js(TypeError, function() { ctx.transform(); });
+ assert_throws_js(TypeError, function() { ctx.transform(1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1, 0); });
+}
+if (ctx.setTransform) {
+ assert_throws_js(TypeError, function() { ctx.setTransform(1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1, 0); });
+}
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0); });
+assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0); });
+assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.createPattern(canvas); });
+assert_throws_js(TypeError, function() { ctx.clearRect(); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.clearRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.fillRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.moveTo(); });
+assert_throws_js(TypeError, function() { ctx.moveTo(0); });
+assert_throws_js(TypeError, function() { ctx.lineTo(); });
+assert_throws_js(TypeError, function() { ctx.lineTo(0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.rect(); });
+assert_throws_js(TypeError, function() { ctx.rect(0); });
+assert_throws_js(TypeError, function() { ctx.rect(0, 0); });
+assert_throws_js(TypeError, function() { ctx.rect(0, 0, 0); });
+assert_throws_js(TypeError, function() { ctx.arc(); });
+assert_throws_js(TypeError, function() { ctx.arc(0); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1); });
+assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1, 0); });
+// (6th argument to arc is optional)
+if (ctx.isPointInPath) {
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(0); });
+}
+if (ctx.drawFocusRing) {
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas, 0); });
+}
+if (ctx.fillText) {
+ assert_throws_js(TypeError, function() { ctx.fillText(); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test'); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeText(); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test'); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.measureText(); });
+}
+assert_throws_js(TypeError, function() { ctx.drawImage(); });
+assert_throws_js(TypeError, function() { ctx.drawImage(canvas); });
+assert_throws_js(TypeError, function() { ctx.drawImage(canvas, 0); });
+// TODO: n >= 3 args on drawImage could be either a valid overload,
+// or too few for another overload, or too many for another
+// overload - what should happen?
+if (ctx.createImageData) {
+ assert_throws_js(TypeError, function() { ctx.createImageData(); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(1); });
+}
+if (ctx.getImageData) {
+ assert_throws_js(TypeError, function() { ctx.getImageData(); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0, 1); });
+}
+if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ assert_throws_js(TypeError, function() { ctx.putImageData(); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0); });
+}
+var g = ctx.createLinearGradient(0, 0, 0, 0);
+assert_throws_js(TypeError, function() { g.addColorStop(); });
+assert_throws_js(TypeError, function() { g.addColorStop(0); });
+t.done();
+
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/META.yml b/testing/web-platform/tests/html/canvas/offscreen/META.yml
new file mode 100644
index 0000000000..d0524194c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/META.yml
@@ -0,0 +1,7 @@
+spec: https://html.spec.whatwg.org/multipage/canvas.html#the-offscreencanvas-interface
+suggested_reviewers:
+ - AmeliaBR
+ - annevk
+ - kenrussell
+ - fserb
+ - Cwiiis
diff --git a/testing/web-platform/tests/html/canvas/offscreen/WEB_FEATURES.yml b/testing/web-platform/tests/html/canvas/offscreen/WEB_FEATURES.yml
new file mode 100644
index 0000000000..b1f003a745
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/WEB_FEATURES.yml
@@ -0,0 +1,3 @@
+features:
+- name: offscreen-canvas
+ files: "**"
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.html
new file mode 100644
index 0000000000..0c9fdc9639
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.arguments.missing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.arguments.missing</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext(); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.worker.js
new file mode 100644
index 0000000000..1b5c857a79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.arguments.missing.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.arguments.missing
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext(); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.html
new file mode 100644
index 0000000000..aed71a37e9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.casesensitive</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.casesensitive</h1>
+<p class="desc">Context name "2D" is unrecognised; matching is case sensitive</p>
+
+
+<script>
+var t = async_test("Context name \"2D\" is unrecognised; matching is case sensitive");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext('2D'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.worker.js
new file mode 100644
index 0000000000..c1df3a9f80
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.casesensitive.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.casesensitive
+// Description:Context name "2D" is unrecognised; matching is case sensitive
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Context name \"2D\" is unrecognised; matching is case sensitive");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext('2D'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.html
new file mode 100644
index 0000000000..10548a6b7c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.emptystring</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.emptystring</h1>
+<p class="desc">getContext with empty string returns null</p>
+
+
+<script>
+var t = async_test("getContext with empty string returns null");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext(""); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.worker.js
new file mode 100644
index 0000000000..53a58c1f5d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.emptystring.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.emptystring
+// Description:getContext with empty string returns null
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getContext with empty string returns null");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext(""); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html
new file mode 100644
index 0000000000..41b5cfee31
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.exists</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.exists</h1>
+<p class="desc">The 2D context is implemented</p>
+
+
+<script>
+var t = async_test("The 2D context is implemented");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ _assertDifferent(offscreenCanvas2.getContext('2d'), null, "offscreenCanvas2.getContext('2d')", "null");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js
new file mode 100644
index 0000000000..77a43530a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.exists
+// Description:The 2D context is implemented
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("The 2D context is implemented");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ _assertDifferent(offscreenCanvas2.getContext('2d'), null, "offscreenCanvas2.getContext('2d')", "null");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html
new file mode 100644
index 0000000000..2bcf34490e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.extraargs.cache</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.extraargs.cache</h1>
+<p class="desc">The 2D context doesn't throw with extra getContext arguments (cached)</p>
+
+
+<script>
+var t = async_test("The 2D context doesn't throw with extra getContext arguments (cached)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(canvas.getContext('2d', false, {}, [], 1, "2"), null, "canvas.getContext('2d', false, {}, [], 1, \"2\")", "null");
+ _assertDifferent(canvas.getContext('2d', 123), null, "canvas.getContext('2d', 123)", "null");
+ _assertDifferent(canvas.getContext('2d', "test"), null, "canvas.getContext('2d', \"test\")", "null");
+ _assertDifferent(canvas.getContext('2d', undefined), null, "canvas.getContext('2d', undefined)", "null");
+ _assertDifferent(canvas.getContext('2d', null), null, "canvas.getContext('2d', null)", "null");
+ _assertDifferent(canvas.getContext('2d', Symbol.hasInstance), null, "canvas.getContext('2d', Symbol.hasInstance)", "null");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js
new file mode 100644
index 0000000000..14284a0a7d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.extraargs.cache
+// Description:The 2D context doesn't throw with extra getContext arguments (cached)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("The 2D context doesn't throw with extra getContext arguments (cached)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(canvas.getContext('2d', false, {}, [], 1, "2"), null, "canvas.getContext('2d', false, {}, [], 1, \"2\")", "null");
+ _assertDifferent(canvas.getContext('2d', 123), null, "canvas.getContext('2d', 123)", "null");
+ _assertDifferent(canvas.getContext('2d', "test"), null, "canvas.getContext('2d', \"test\")", "null");
+ _assertDifferent(canvas.getContext('2d', undefined), null, "canvas.getContext('2d', undefined)", "null");
+ _assertDifferent(canvas.getContext('2d', null), null, "canvas.getContext('2d', null)", "null");
+ _assertDifferent(canvas.getContext('2d', Symbol.hasInstance), null, "canvas.getContext('2d', Symbol.hasInstance)", "null");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html
new file mode 100644
index 0000000000..029122355c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.extraargs.create</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.extraargs.create</h1>
+<p class="desc">The 2D context doesn't throw with extra getContext arguments (new context)</p>
+
+
+<script>
+var t = async_test("The 2D context doesn't throw with extra getContext arguments (new context)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, "2"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, \"2\")", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', 123), null, "(new OffscreenCanvas(100, 50)).getContext('2d', 123)", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', "test"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', \"test\")", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', undefined), null, "(new OffscreenCanvas(100, 50)).getContext('2d', undefined)", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', null), null, "(new OffscreenCanvas(100, 50)).getContext('2d', null)", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance), null, "(new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance)", "null");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js
new file mode 100644
index 0000000000..b4208edba8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.extraargs.create
+// Description:The 2D context doesn't throw with extra getContext arguments (new context)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("The 2D context doesn't throw with extra getContext arguments (new context)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, "2"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, \"2\")", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', 123), null, "(new OffscreenCanvas(100, 50)).getContext('2d', 123)", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', "test"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', \"test\")", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', undefined), null, "(new OffscreenCanvas(100, 50)).getContext('2d', undefined)", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', null), null, "(new OffscreenCanvas(100, 50)).getContext('2d', null)", "null");
+ _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance), null, "(new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance)", "null");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.html
new file mode 100644
index 0000000000..cb9501747e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.shared</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.shared</h1>
+<p class="desc">getContext('2d') returns objects which share canvas state</p>
+
+
+<script>
+var t = async_test("getContext('2d') returns objects which share canvas state");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var ctx2 = canvas.getContext('2d');
+ ctx.fillStyle = '#f00';
+ ctx2.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.worker.js
new file mode 100644
index 0000000000..8e53475756
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.shared.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.shared
+// Description:getContext('2d') returns objects which share canvas state
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getContext('2d') returns objects which share canvas state");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var ctx2 = canvas.getContext('2d');
+ ctx.fillStyle = '#f00';
+ ctx2.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html
new file mode 100644
index 0000000000..66e4a049ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.unique</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.unique</h1>
+<p class="desc">getContext('2d') returns the same object</p>
+
+
+<script>
+var t = async_test("getContext('2d') returns the same object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ _assertSame(offscreenCanvas2.getContext('2d'), offscreenCanvas2.getContext('2d'), "offscreenCanvas2.getContext('2d')", "offscreenCanvas2.getContext('2d')");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js
new file mode 100644
index 0000000000..275e45fde6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.unique
+// Description:getContext('2d') returns the same object
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getContext('2d') returns the same object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ _assertSame(offscreenCanvas2.getContext('2d'), offscreenCanvas2.getContext('2d'), "offscreenCanvas2.getContext('2d')", "offscreenCanvas2.getContext('2d')");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.html
new file mode 100644
index 0000000000..4313f40843
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.badname</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.unrecognised.badname</h1>
+<p class="desc">getContext with unrecognised context name returns null</p>
+
+
+<script>
+var t = async_test("getContext with unrecognised context name returns null");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext('This is not an implemented context in any real browser'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.worker.js
new file mode 100644
index 0000000000..dd16f2fbe1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.badname
+// Description:getContext with unrecognised context name returns null
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getContext with unrecognised context name returns null");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext('This is not an implemented context in any real browser'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.html
new file mode 100644
index 0000000000..c00afa686e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.badsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.unrecognised.badsuffix</h1>
+<p class="desc">Context name "2d" plus a suffix is unrecognised</p>
+
+
+<script>
+var t = async_test("Context name \"2d\" plus a suffix is unrecognised");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d#"); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.worker.js
new file mode 100644
index 0000000000..5e684c92c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.badsuffix
+// Description:Context name "2d" plus a suffix is unrecognised
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Context name \"2d\" plus a suffix is unrecognised");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d#"); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.html
new file mode 100644
index 0000000000..0ce3d4195e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.nullsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.unrecognised.nullsuffix</h1>
+<p class="desc">Context name "2d" plus a "\0" suffix is unrecognised</p>
+
+
+<script>
+var t = async_test("Context name \"2d\" plus a \"\\0\" suffix is unrecognised");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d\0"); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.worker.js
new file mode 100644
index 0000000000..2886010fb6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.nullsuffix
+// Description:Context name "2d" plus a "\0" suffix is unrecognised
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Context name \"2d\" plus a \"\\0\" suffix is unrecognised");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d\0"); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.html
new file mode 100644
index 0000000000..316123675a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.unicode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.unrecognised.unicode</h1>
+<p class="desc">Context name which kind of looks like "2d" is unrecognised</p>
+
+
+<script>
+var t = async_test("Context name which kind of looks like \"2d\" is unrecognised");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2\uFF44"); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.worker.js
new file mode 100644
index 0000000000..46e562dd48
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.unicode
+// Description:Context name which kind of looks like "2d" is unrecognised
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Context name which kind of looks like \"2d\" is unrecognised");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2\uFF44"); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.getContext.options.any.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.getContext.options.any.js
new file mode 100644
index 0000000000..930f7722ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-context/2d.getContext.options.any.js
@@ -0,0 +1,46 @@
+test(() => {
+ const expected = [
+ "alpha",
+ "colorSpace",
+ "colorSpace toString",
+ "desynchronized",
+ "willReadFrequently",
+ ];
+ var actual = [];
+ const options = {
+ get alpha() {
+ actual.push("alpha");
+ return true;
+ },
+ get willReadFrequently() {
+ actual.push("willReadFrequently");
+ return false;
+ },
+ get desynchronized() {
+ actual.push("desynchronized");
+ return false;
+ },
+ get colorSpace() {
+ actual.push("colorSpace");
+ return {
+ toString() {
+ actual.push("colorSpace toString");
+ return "srgb";
+ }
+ };
+ },
+ };
+
+ const canvas = new OffscreenCanvas(100, 50);
+ const context = canvas.getContext('2d', options);
+ assert_not_equals(context, null, "context");
+ assert_array_equals(actual, expected, "order of operations (creation)");
+ actual = [];
+ assert_equals(canvas.getContext('2d', options), context, "cached context");
+ // Getting the cached context does not involve the options argument at all;
+ // the context retains its existing settings, and the new options (if any)
+ // are ignored.
+ // Therefore, there is no expectation that the 'options' dictionary will be
+ // accessed again here, and we cannot predict the contents, if any, of the
+ // 'actual' array.
+});
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.html
new file mode 100644
index 0000000000..0793c74f39
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.color</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.color</h1>
+<p class="desc">Initial state is transparent black</p>
+
+
+<script>
+var t = async_test("Initial state is transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.worker.js
new file mode 100644
index 0000000000..11d6b9f098
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.color.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.color
+// Description:Initial state is transparent black
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Initial state is transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.html
new file mode 100644
index 0000000000..36230dab77
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.2dstate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.2dstate</h1>
+<p class="desc">Resetting the canvas state resets 2D state variables</p>
+
+
+<script>
+var t = async_test("Resetting the canvas state resets 2D state variables");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ var default_val;
+
+ default_val = ctx.strokeStyle;
+ ctx.strokeStyle = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.strokeStyle, default_val, "ctx.strokeStyle", "default_val");
+
+ default_val = ctx.fillStyle;
+ ctx.fillStyle = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.fillStyle, default_val, "ctx.fillStyle", "default_val");
+
+ default_val = ctx.globalAlpha;
+ ctx.globalAlpha = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.globalAlpha, default_val, "ctx.globalAlpha", "default_val");
+
+ default_val = ctx.lineWidth;
+ ctx.lineWidth = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.lineWidth, default_val, "ctx.lineWidth", "default_val");
+
+ default_val = ctx.lineCap;
+ ctx.lineCap = "round";
+ canvas.width = 100;
+ _assertSame(ctx.lineCap, default_val, "ctx.lineCap", "default_val");
+
+ default_val = ctx.lineJoin;
+ ctx.lineJoin = "round";
+ canvas.width = 100;
+ _assertSame(ctx.lineJoin, default_val, "ctx.lineJoin", "default_val");
+
+ default_val = ctx.miterLimit;
+ ctx.miterLimit = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.miterLimit, default_val, "ctx.miterLimit", "default_val");
+
+ default_val = ctx.shadowOffsetX;
+ ctx.shadowOffsetX = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowOffsetX, default_val, "ctx.shadowOffsetX", "default_val");
+
+ default_val = ctx.shadowOffsetY;
+ ctx.shadowOffsetY = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowOffsetY, default_val, "ctx.shadowOffsetY", "default_val");
+
+ default_val = ctx.shadowBlur;
+ ctx.shadowBlur = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowBlur, default_val, "ctx.shadowBlur", "default_val");
+
+ default_val = ctx.shadowColor;
+ ctx.shadowColor = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.shadowColor, default_val, "ctx.shadowColor", "default_val");
+
+ default_val = ctx.globalCompositeOperation;
+ ctx.globalCompositeOperation = "copy";
+ canvas.width = 100;
+ _assertSame(ctx.globalCompositeOperation, default_val, "ctx.globalCompositeOperation", "default_val");
+
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.worker.js
new file mode 100644
index 0000000000..df0bd9f63c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.2dstate.worker.js
@@ -0,0 +1,84 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.2dstate
+// Description:Resetting the canvas state resets 2D state variables
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Resetting the canvas state resets 2D state variables");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ var default_val;
+
+ default_val = ctx.strokeStyle;
+ ctx.strokeStyle = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.strokeStyle, default_val, "ctx.strokeStyle", "default_val");
+
+ default_val = ctx.fillStyle;
+ ctx.fillStyle = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.fillStyle, default_val, "ctx.fillStyle", "default_val");
+
+ default_val = ctx.globalAlpha;
+ ctx.globalAlpha = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.globalAlpha, default_val, "ctx.globalAlpha", "default_val");
+
+ default_val = ctx.lineWidth;
+ ctx.lineWidth = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.lineWidth, default_val, "ctx.lineWidth", "default_val");
+
+ default_val = ctx.lineCap;
+ ctx.lineCap = "round";
+ canvas.width = 100;
+ _assertSame(ctx.lineCap, default_val, "ctx.lineCap", "default_val");
+
+ default_val = ctx.lineJoin;
+ ctx.lineJoin = "round";
+ canvas.width = 100;
+ _assertSame(ctx.lineJoin, default_val, "ctx.lineJoin", "default_val");
+
+ default_val = ctx.miterLimit;
+ ctx.miterLimit = 0.5;
+ canvas.width = 100;
+ _assertSame(ctx.miterLimit, default_val, "ctx.miterLimit", "default_val");
+
+ default_val = ctx.shadowOffsetX;
+ ctx.shadowOffsetX = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowOffsetX, default_val, "ctx.shadowOffsetX", "default_val");
+
+ default_val = ctx.shadowOffsetY;
+ ctx.shadowOffsetY = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowOffsetY, default_val, "ctx.shadowOffsetY", "default_val");
+
+ default_val = ctx.shadowBlur;
+ ctx.shadowBlur = 5;
+ canvas.width = 100;
+ _assertSame(ctx.shadowBlur, default_val, "ctx.shadowBlur", "default_val");
+
+ default_val = ctx.shadowColor;
+ ctx.shadowColor = "#ff0000";
+ canvas.width = 100;
+ _assertSame(ctx.shadowColor, default_val, "ctx.shadowColor", "default_val");
+
+ default_val = ctx.globalCompositeOperation;
+ ctx.globalCompositeOperation = "copy";
+ canvas.width = 100;
+ _assertSame(ctx.globalCompositeOperation, default_val, "ctx.globalCompositeOperation", "default_val");
+
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.html
new file mode 100644
index 0000000000..fc53240795
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.clip</h1>
+<p class="desc">Resetting the canvas state resets the current clip region</p>
+
+
+<script>
+var t = async_test("Resetting the canvas state resets the current clip region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ canvas.width = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.worker.js
new file mode 100644
index 0000000000..80554b0a3f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.clip.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.clip
+// Description:Resetting the canvas state resets the current clip region
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Resetting the canvas state resets the current clip region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ canvas.width = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.html
new file mode 100644
index 0000000000..3771a5e37a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.different</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.different</h1>
+<p class="desc">Changing size resets canvas to transparent black</p>
+
+
+<script>
+var t = async_test("Changing size resets canvas to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 20,20, 255,0,0,255);
+ canvas.width = 50;
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.worker.js
new file mode 100644
index 0000000000..6074d4f2a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.different.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.different
+// Description:Changing size resets canvas to transparent black
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Changing size resets canvas to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 20,20, 255,0,0,255);
+ canvas.width = 50;
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.html
new file mode 100644
index 0000000000..387b4d1f1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.gradient</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.gradient</h1>
+<p class="desc">Resetting the canvas state does not invalidate any existing gradients</p>
+
+
+<script>
+var t = async_test("Resetting the canvas state does not invalidate any existing gradients");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 50;
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.worker.js
new file mode 100644
index 0000000000..9029b48056
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.gradient.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.gradient
+// Description:Resetting the canvas state does not invalidate any existing gradients
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Resetting the canvas state does not invalidate any existing gradients");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 50;
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.html
new file mode 100644
index 0000000000..3a887a8f1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.path</h1>
+<p class="desc">Resetting the canvas state resets the current path</p>
+
+
+<script>
+var t = async_test("Resetting the canvas state resets the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.rect(0, 0, 100, 50);
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.worker.js
new file mode 100644
index 0000000000..0ab12872ae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.path.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.path
+// Description:Resetting the canvas state resets the current path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Resetting the canvas state resets the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.rect(0, 0, 100, 50);
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.html
new file mode 100644
index 0000000000..d822f90917
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.pattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.pattern</h1>
+<p class="desc">Resetting the canvas state does not invalidate any existing patterns</p>
+
+
+<script>
+var t = async_test("Resetting the canvas state does not invalidate any existing patterns");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 30;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 30, 50);
+ var p = ctx.createPattern(canvas, 'repeat-x');
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = p;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.worker.js
new file mode 100644
index 0000000000..c4870a6f99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.pattern.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.pattern
+// Description:Resetting the canvas state does not invalidate any existing patterns
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Resetting the canvas state does not invalidate any existing patterns");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 30;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 30, 50);
+ var p = ctx.createPattern(canvas, 'repeat-x');
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = p;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.html
new file mode 100644
index 0000000000..19394def37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.same</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.same</h1>
+<p class="desc">Setting size (not changing the value) resets canvas to transparent black</p>
+
+
+<script>
+var t = async_test("Setting size (not changing the value) resets canvas to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 20,20, 255,0,0,255);
+ canvas.width = 100;
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.worker.js
new file mode 100644
index 0000000000..48d24750ac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.same.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.same
+// Description:Setting size (not changing the value) resets canvas to transparent black
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting size (not changing the value) resets canvas to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 20,20, 255,0,0,255);
+ canvas.width = 100;
+ _assertPixel(canvas, 20,20, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.html
new file mode 100644
index 0000000000..ee3b5abf10
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.initial.reset.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.initial.reset.transform</h1>
+<p class="desc">Resetting the canvas state resets the current transformation matrix</p>
+
+
+<script>
+var t = async_test("Resetting the canvas state resets the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.scale(0.1, 0.1);
+ canvas.width = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.worker.js
new file mode 100644
index 0000000000..218e64fa5d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.initial.reset.transform.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.initial.reset.transform
+// Description:Resetting the canvas state resets the current transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Resetting the canvas state resets the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 100;
+ ctx.scale(0.1, 0.1);
+ canvas.width = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html
new file mode 100644
index 0000000000..0e7e10cd24
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.readonly</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.readonly</h1>
+<p class="desc">canvas is readonly</p>
+
+
+<script>
+var t = async_test("canvas is readonly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var d = ctx.canvas;
+ _assertDifferent(offscreenCanvas2, d, "offscreenCanvas2", "d");
+ ctx.canvas = offscreenCanvas2;
+ _assertSame(ctx.canvas, d, "ctx.canvas", "d");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js
new file mode 100644
index 0000000000..bbe50dcf61
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.readonly
+// Description:canvas is readonly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("canvas is readonly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var d = ctx.canvas;
+ _assertDifferent(offscreenCanvas2, d, "offscreenCanvas2", "d");
+ ctx.canvas = offscreenCanvas2;
+ _assertSame(ctx.canvas, d, "ctx.canvas", "d");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.html
new file mode 100644
index 0000000000..b5de73f403
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.reference</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.reference</h1>
+<p class="desc">canvas refers back to its canvas</p>
+
+
+<script>
+var t = async_test("canvas refers back to its canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.canvas, canvas, "ctx.canvas", "canvas");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.worker.js
new file mode 100644
index 0000000000..7a1f0c5ab4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.reference.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.reference
+// Description:canvas refers back to its canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("canvas refers back to its canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.canvas, canvas, "ctx.canvas", "canvas");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.html
new file mode 100644
index 0000000000..dc7b894b20
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.default</h1>
+<p class="desc">Default width/height when attributes are missing</p>
+
+
+<script>
+var t = async_test("Default width/height when attributes are missing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 50, "canvas.height", "50");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.worker.js
new file mode 100644
index 0000000000..78fce5aef8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.default.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.default
+// Description:Default width/height when attributes are missing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Default width/height when attributes are missing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 50, "canvas.height", "50");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html
new file mode 100644
index 0000000000..7030103524
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.idl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.idl</h1>
+<p class="desc">Getting/setting width/height IDL attributes</p>
+
+
+<script>
+var t = async_test("Getting/setting width/height IDL attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = "100";
+ canvas.height = "100";
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ canvas.width = "+1.5e2";
+ canvas.height = "0x96";
+ _assertSame(canvas.width, 150, "canvas.width", "150");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ canvas.width = 301.999;
+ canvas.height = 301.001;
+ _assertSame(canvas.width, 301, "canvas.width", "301");
+ _assertSame(canvas.height, 301, "canvas.height", "301");
+ assert_throws_js(TypeError, function() { canvas.width = "400x"; });
+ assert_throws_js(TypeError, function() { canvas.height = "foo"; });
+ _assertSame(canvas.width, 301, "canvas.width", "301");
+ _assertSame(canvas.height, 301, "canvas.height", "301");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.html
new file mode 100644
index 0000000000..347c460cd7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.idl.set.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.idl.set.zero</h1>
+<p class="desc">Setting width/height IDL attributes to 0</p>
+
+
+<script>
+var t = async_test("Setting width/height IDL attributes to 0");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 0;
+ canvas.height = 0;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.worker.js
new file mode 100644
index 0000000000..21535da0eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.idl.set.zero
+// Description:Setting width/height IDL attributes to 0
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting width/height IDL attributes to 0");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 0;
+ canvas.height = 0;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js
new file mode 100644
index 0000000000..a00201f18c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.idl
+// Description:Getting/setting width/height IDL attributes
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Getting/setting width/height IDL attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = "100";
+ canvas.height = "100";
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ canvas.width = "+1.5e2";
+ canvas.height = "0x96";
+ _assertSame(canvas.width, 150, "canvas.width", "150");
+ _assertSame(canvas.height, 150, "canvas.height", "150");
+ canvas.width = 301.999;
+ canvas.height = 301.001;
+ _assertSame(canvas.width, 301, "canvas.width", "301");
+ _assertSame(canvas.height, 301, "canvas.height", "301");
+ assert_throws_js(TypeError, function() { canvas.width = "400x"; });
+ assert_throws_js(TypeError, function() { canvas.height = "foo"; });
+ _assertSame(canvas.width, 301, "canvas.width", "301");
+ _assertSame(canvas.height, 301, "canvas.height", "301");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html
new file mode 100644
index 0000000000..c3fa3b4ba6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.decimal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.decimal</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '100.999';
+ canvas.height = '100.999';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.worker.js
new file mode 100644
index 0000000000..1267bb205a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.decimal.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.decimal
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '100.999';
+ canvas.height = '100.999';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.html
new file mode 100644
index 0000000000..ea6f811b8f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.em</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.em</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '100em'; });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.worker.js
new file mode 100644
index 0000000000..2f0642d997
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.em.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.em
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '100em'; });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.html
new file mode 100644
index 0000000000..d38c159a6e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.empty</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '';
+ canvas.height = '';
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.worker.js
new file mode 100644
index 0000000000..b1eee3a5b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.empty.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.empty
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '';
+ canvas.height = '';
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.html
new file mode 100644
index 0000000000..2aa8245a49
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.exp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.exp</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '100e1';
+ canvas.height = '100e1';
+ _assertSame(canvas.width, 1000.0, "canvas.width", "1000.0");
+ _assertSame(canvas.height, 1000.0, "canvas.height", "1000.0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.worker.js
new file mode 100644
index 0000000000..8c8b4cc715
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.exp.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.exp
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '100e1';
+ canvas.height = '100e1';
+ _assertSame(canvas.width, 1000.0, "canvas.width", "1000.0");
+ _assertSame(canvas.height, 1000.0, "canvas.height", "1000.0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.html
new file mode 100644
index 0000000000..4b0e47b53f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.hex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.hex</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '0x100';
+ canvas.height = '0x100';
+ _assertSame(canvas.width, 256, "canvas.width", "256");
+ _assertSame(canvas.height, 256, "canvas.height", "256");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.worker.js
new file mode 100644
index 0000000000..b685aaffa2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.hex.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.hex
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '0x100';
+ canvas.height = '0x100';
+ _assertSame(canvas.width, 256, "canvas.width", "256");
+ _assertSame(canvas.height, 256, "canvas.height", "256");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.html
new file mode 100644
index 0000000000..a619651f78
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.junk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.junk</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '#!?'; });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.worker.js
new file mode 100644
index 0000000000..f4822f4bd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.junk.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.junk
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '#!?'; });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.html
new file mode 100644
index 0000000000..c7f12fdb02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.minus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.minus</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '-100'; });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.worker.js
new file mode 100644
index 0000000000..322b992eda
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.minus.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.minus
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '-100'; });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.html
new file mode 100644
index 0000000000..7bfb7658d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.octal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.octal</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '0100';
+ canvas.height = '0100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.worker.js
new file mode 100644
index 0000000000..ce518e35c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.octal.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.octal
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '0100';
+ canvas.height = '0100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html
new file mode 100644
index 0000000000..16dace16ea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.onlyspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.onlyspace</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = ' ';
+ canvas.height = ' ';
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.worker.js
new file mode 100644
index 0000000000..c186a4c08b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.onlyspace.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.onlyspace
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = ' ';
+ canvas.height = ' ';
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.html
new file mode 100644
index 0000000000..040a775ec7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.percent</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '100%'; });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.worker.js
new file mode 100644
index 0000000000..f38a1862d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.percent.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.percent
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '100%'; });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.html
new file mode 100644
index 0000000000..50c8467e2c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.plus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.plus</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '+100';
+ canvas.height = '+100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.worker.js
new file mode 100644
index 0000000000..bb45a1e4fa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.plus.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.plus
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '+100';
+ canvas.height = '+100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.html
new file mode 100644
index 0000000000..cb1f3ae840
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.space</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = ' 100';
+ canvas.height = ' 100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.worker.js
new file mode 100644
index 0000000000..967a0939d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.space.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.space
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = ' 100';
+ canvas.height = ' 100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html
new file mode 100644
index 0000000000..8d8d481aef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.trailingjunk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.trailingjunk</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '100#!?'; });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.worker.js
new file mode 100644
index 0000000000..ffebcd97f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.trailingjunk.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.trailingjunk
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { canvas.width = '100#!?'; });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html
new file mode 100644
index 0000000000..f6e29d6cb6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.whitespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.whitespace</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = ' 100';
+ canvas.height = ' 100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.worker.js
new file mode 100644
index 0000000000..fb7ba47975
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.whitespace.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.whitespace
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = ' 100';
+ canvas.height = ' 100';
+ _assertSame(canvas.width, 100, "canvas.width", "100");
+ _assertSame(canvas.height, 100, "canvas.height", "100");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.html
new file mode 100644
index 0000000000..07e924a603
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.parse.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.parse.zero</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<script>
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '0';
+ canvas.height = '0';
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.worker.js
new file mode 100644
index 0000000000..1363bff772
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.parse.zero.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.parse.zero
+// Description:Parsing of non-negative integers
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Parsing of non-negative integers");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = '0';
+ canvas.height = '0';
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.html
new file mode 100644
index 0000000000..d24b2cc49f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.reflect.setidl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.reflect.setidl</h1>
+<p class="desc">Setting IDL attributes updates IDL and content attributes</p>
+
+
+<script>
+var t = async_test("Setting IDL attributes updates IDL and content attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 120;
+ canvas.height = 60;
+ _assertSame(canvas.width, 120, "canvas.width", "120");
+ _assertSame(canvas.height, 60, "canvas.height", "60");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.worker.js
new file mode 100644
index 0000000000..3b3ced124a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.reflect.setidl
+// Description:Setting IDL attributes updates IDL and content attributes
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting IDL attributes updates IDL and content attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 120;
+ canvas.height = 60;
+ _assertSame(canvas.width, 120, "canvas.width", "120");
+ _assertSame(canvas.height, 60, "canvas.height", "60");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.html
new file mode 100644
index 0000000000..c4839afb0e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.attributes.reflect.setidlzero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.attributes.reflect.setidlzero</h1>
+<p class="desc">Setting IDL attributes to 0 updates IDL and content attributes</p>
+
+
+<script>
+var t = async_test("Setting IDL attributes to 0 updates IDL and content attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 0;
+ canvas.height = 0;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.worker.js
new file mode 100644
index 0000000000..d440a9d807
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.attributes.reflect.setidlzero
+// Description:Setting IDL attributes to 0 updates IDL and content attributes
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting IDL attributes to 0 updates IDL and content attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 0;
+ canvas.height = 0;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html
new file mode 100644
index 0000000000..b220f8f2ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.large</h1>
+<p class="desc"></p>
+
+<p class="notes">Not sure how reasonable this is, but the spec doesn't say there's an upper limit on the size.
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
+ canvas.width = n;
+ canvas.height = n;
+ _assertSame(canvas.width, n, "canvas.width", "n");
+ _assertSame(canvas.height, n, "canvas.height", "n");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.js b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.js
new file mode 100644
index 0000000000..a763704131
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.large
+// Description:
+// Note:<p class="notes">Not sure how reasonable this is, but the spec doesn't say there's an upper limit on the size.
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
+ canvas.width = n;
+ canvas.height = n;
+ _assertSame(canvas.width, n, "canvas.width", "n");
+ _assertSame(canvas.height, n, "canvas.height", "n");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.html
new file mode 100644
index 0000000000..eac9dbdef9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.clear</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.worker.js
new file mode 100644
index 0000000000..2f9fb92da1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.clear.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.clear
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.html
new file mode 100644
index 0000000000..7c9771c10f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.copy</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,191, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.worker.js
new file mode 100644
index 0000000000..5b071665ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.copy.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.copy
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,191, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.html
new file mode 100644
index 0000000000..d9c34ded0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.destination-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 128,255,128,191, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.worker.js
new file mode 100644
index 0000000000..58828619a3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-atop.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.destination-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 128,255,128,191, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.html
new file mode 100644
index 0000000000..9c1a8dbf47
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.destination-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,96, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.worker.js
new file mode 100644
index 0000000000..4e2ec058ec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-in.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.destination-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,96, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.html
new file mode 100644
index 0000000000..10c5baf485
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.destination-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,32, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.worker.js
new file mode 100644
index 0000000000..bc7be056a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-out.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.destination-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,32, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.html
new file mode 100644
index 0000000000..0e2ece9eab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.destination-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 109,255,146,223, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.worker.js
new file mode 100644
index 0000000000..c1d15a0959
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.destination-over.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.destination-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 109,255,146,223, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.html
new file mode 100644
index 0000000000..392bb855f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.lighter</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,128,255, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.worker.js
new file mode 100644
index 0000000000..df494f22d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.lighter.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.lighter
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,128,255, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.html
new file mode 100644
index 0000000000..f7d4da4d84
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.source-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.worker.js
new file mode 100644
index 0000000000..781a89c1b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-atop.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.source-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.html
new file mode 100644
index 0000000000..69e57e2578
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.source-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.worker.js
new file mode 100644
index 0000000000..484399acfc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-in.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.source-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.html
new file mode 100644
index 0000000000..eb9dbd0810
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.source-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.worker.js
new file mode 100644
index 0000000000..d0d6cc12e9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-out.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.source-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.html
new file mode 100644
index 0000000000..98629de8a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.source-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 219,255,36,223, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.worker.js
new file mode 100644
index 0000000000..848fbf3bec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.source-over.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.source-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 219,255,36,223, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.html
new file mode 100644
index 0000000000..bc69c8a08b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.canvas.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.canvas.xor</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.worker.js
new file mode 100644
index 0000000000..250bba4bac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.canvas.xor.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.canvas.xor
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.html
new file mode 100644
index 0000000000..f0e9989cce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.clear</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.worker.js
new file mode 100644
index 0000000000..abae05ac24
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.clear.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.clear
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.html
new file mode 100644
index 0000000000..2471cd7edd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.copy</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.worker.js
new file mode 100644
index 0000000000..dfebd98a6b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.copy.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.copy
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.html
new file mode 100644
index 0000000000..efb5e7ab6d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.destination-atop</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.worker.js
new file mode 100644
index 0000000000..9c8fa79c5a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-atop.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.destination-atop
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.html
new file mode 100644
index 0000000000..bc467a1d99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.destination-in</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.worker.js
new file mode 100644
index 0000000000..a98624f824
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-in.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.destination-in
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.html
new file mode 100644
index 0000000000..674ec3aeb8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.destination-out</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.worker.js
new file mode 100644
index 0000000000..0cf915d1c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-out.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.destination-out
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.html
new file mode 100644
index 0000000000..6abd0af788
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.destination-over</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.worker.js
new file mode 100644
index 0000000000..b1b5eee6f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.destination-over.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.destination-over
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.html
new file mode 100644
index 0000000000..00782a683e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.lighter</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.worker.js
new file mode 100644
index 0000000000..8576d9db7c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.lighter.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.lighter
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.html
new file mode 100644
index 0000000000..a7dc6a3bc8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.source-atop</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.worker.js
new file mode 100644
index 0000000000..fd220f52b3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-atop.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.source-atop
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.html
new file mode 100644
index 0000000000..3f24076161
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.source-in</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.worker.js
new file mode 100644
index 0000000000..0c61fb7794
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-in.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.source-in
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.html
new file mode 100644
index 0000000000..4033893b2b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.source-out</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.worker.js
new file mode 100644
index 0000000000..ec57663af1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-out.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.source-out
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.html
new file mode 100644
index 0000000000..5b48161c65
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.source-over</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.worker.js
new file mode 100644
index 0000000000..15c322ee59
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.source-over.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.source-over
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.html
new file mode 100644
index 0000000000..0156e4a2ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.clip.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.clip.xor</h1>
+<p class="desc">fill() does not affect pixels outside the clip region.</p>
+
+
+<script>
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.worker.js
new file mode 100644
index 0000000000..30bae44aa9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.clip.xor.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.clip.xor
+// Description:fill() does not affect pixels outside the clip region.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() does not affect pixels outside the clip region.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.html
new file mode 100644
index 0000000000..c096253e27
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.canvas</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.worker.js
new file mode 100644
index 0000000000..ede4733a83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvas.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.canvas
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.html
new file mode 100644
index 0000000000..2eb06556ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.canvascopy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.canvascopy</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy'
+ ctx.globalAlpha = 0.51;
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,130, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.worker.js
new file mode 100644
index 0000000000..f61859d231
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvascopy.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.canvascopy
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy'
+ ctx.globalAlpha = 0.51;
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,130, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.html
new file mode 100644
index 0000000000..cbfe111092
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.canvaspattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.canvaspattern</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(offscreenCanvas2, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.worker.js
new file mode 100644
index 0000000000..7ecd568fae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.canvaspattern.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.canvaspattern
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(offscreenCanvas2, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.html
new file mode 100644
index 0000000000..57c3745d4e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.default</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.globalAlpha, 1.0, "ctx.globalAlpha", "1.0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.worker.js
new file mode 100644
index 0000000000..8acbd6a37f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.default.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.default
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.globalAlpha, 1.0, "ctx.globalAlpha", "1.0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.html
new file mode 100644
index 0000000000..7b31db198e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.fill</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.fill</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.worker.js
new file mode 100644
index 0000000000..3ea8aa7ebe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.fill.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.fill
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.html
new file mode 100644
index 0000000000..4590a2ea1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.image</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.worker.js
new file mode 100644
index 0000000000..20953417cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.image.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.image
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.html
new file mode 100644
index 0000000000..2fcbca84d2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.imagepattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.imagepattern</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.worker.js
new file mode 100644
index 0000000000..c6ab163b65
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.imagepattern.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.imagepattern
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 2,253,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.html
new file mode 100644
index 0000000000..9bcf85f1c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ ctx.globalAlpha = Infinity;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = -Infinity;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = NaN;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.worker.js
new file mode 100644
index 0000000000..4ca577ad44
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.invalid.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ ctx.globalAlpha = Infinity;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = -Infinity;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = NaN;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.html
new file mode 100644
index 0000000000..c064a41cbd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.globalAlpha.range</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.globalAlpha.range</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = 1.1;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = -0.1;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = 0;
+ _assertSame(ctx.globalAlpha, 0, "ctx.globalAlpha", "0");
+ ctx.globalAlpha = 1;
+ _assertSame(ctx.globalAlpha, 1, "ctx.globalAlpha", "1");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.worker.js
new file mode 100644
index 0000000000..76ea819909
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.globalAlpha.range.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.globalAlpha.range
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = 1.1;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = -0.1;
+ _assertSame(ctx.globalAlpha, a, "ctx.globalAlpha", "a");
+ ctx.globalAlpha = 0;
+ _assertSame(ctx.globalAlpha, 0, "ctx.globalAlpha", "0");
+ ctx.globalAlpha = 1;
+ _assertSame(ctx.globalAlpha, 1, "ctx.globalAlpha", "1");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.html
new file mode 100644
index 0000000000..f001c4409c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.clear</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.worker.js
new file mode 100644
index 0000000000..f152cee739
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.clear.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.clear
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.html
new file mode 100644
index 0000000000..d472a0682d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.copy</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,191, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.worker.js
new file mode 100644
index 0000000000..05ccab1711
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.copy.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.copy
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,191, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.html
new file mode 100644
index 0000000000..753c460ec6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.destination-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 128,255,128,191, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.worker.js
new file mode 100644
index 0000000000..43648142d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-atop.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.destination-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 128,255,128,191, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.html
new file mode 100644
index 0000000000..df9f1ae786
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.destination-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,96, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.worker.js
new file mode 100644
index 0000000000..2787237c56
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-in.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.destination-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,96, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.html
new file mode 100644
index 0000000000..6981ca1d72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.destination-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,32, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.worker.js
new file mode 100644
index 0000000000..e030f533a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-out.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.destination-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,32, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.html
new file mode 100644
index 0000000000..3360115133
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.destination-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 109,255,146,223, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.worker.js
new file mode 100644
index 0000000000..964df4ae8b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.destination-over.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.destination-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 109,255,146,223, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.html
new file mode 100644
index 0000000000..25f2a7684a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.lighter</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,128,255, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.worker.js
new file mode 100644
index 0000000000..f3828b6411
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.lighter.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.lighter
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,128,255, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.html
new file mode 100644
index 0000000000..cfa386cfd1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.source-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.worker.js
new file mode 100644
index 0000000000..7b1618e3f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-atop.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.source-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.html
new file mode 100644
index 0000000000..cc44706b1c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.source-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.worker.js
new file mode 100644
index 0000000000..9accfb35c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-in.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.source-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.html
new file mode 100644
index 0000000000..bc2f7f2633
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.source-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.worker.js
new file mode 100644
index 0000000000..8e8d9116bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-out.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.source-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,96, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.html
new file mode 100644
index 0000000000..88a8176f7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.source-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 219,255,36,223, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.worker.js
new file mode 100644
index 0000000000..679aa19ef9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.source-over.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.source-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 219,255,36,223, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.html
new file mode 100644
index 0000000000..ef149b2f99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.image.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.image.xor</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.worker.js
new file mode 100644
index 0000000000..83a04928b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.image.xor.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.image.xor
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 191,255,64,128, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.html
new file mode 100644
index 0000000000..f21b92f83e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.casesensitive</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.casesensitive</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'Source-over';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.worker.js
new file mode 100644
index 0000000000..db1b54f5ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.casesensitive.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.casesensitive
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'Source-over';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.html
new file mode 100644
index 0000000000..02496b6d89
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.clear</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'clear';
+ _assertSame(ctx.globalCompositeOperation, 'clear', "ctx.globalCompositeOperation", "'clear'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.worker.js
new file mode 100644
index 0000000000..947dd16c5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.clear.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.clear
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'clear';
+ _assertSame(ctx.globalCompositeOperation, 'clear', "ctx.globalCompositeOperation", "'clear'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.html
new file mode 100644
index 0000000000..29dc039157
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.darker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.darker</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'darker';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.worker.js
new file mode 100644
index 0000000000..528f6b93d9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.darker.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.darker
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'darker';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.html
new file mode 100644
index 0000000000..106c0e73f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.default</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.globalCompositeOperation, 'source-over', "ctx.globalCompositeOperation", "'source-over'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.worker.js
new file mode 100644
index 0000000000..ffdb75ad75
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.default.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.default
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.globalCompositeOperation, 'source-over', "ctx.globalCompositeOperation", "'source-over'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.html
new file mode 100644
index 0000000000..1ade1a4e54
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.get</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.get</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
+ 'destination-atop', 'destination-in', 'destination-out', 'destination-over',
+ 'lighter', 'copy', 'xor'];
+ for (var i = 0; i < modes.length; ++i)
+ {
+ ctx.globalCompositeOperation = modes[i];
+ _assertSame(ctx.globalCompositeOperation, modes[i], "ctx.globalCompositeOperation", "modes[\""+(i)+"\"]");
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.worker.js
new file mode 100644
index 0000000000..a266f1d537
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.get.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.get
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
+ 'destination-atop', 'destination-in', 'destination-out', 'destination-over',
+ 'lighter', 'copy', 'xor'];
+ for (var i = 0; i < modes.length; ++i)
+ {
+ ctx.globalCompositeOperation = modes[i];
+ _assertSame(ctx.globalCompositeOperation, modes[i], "ctx.globalCompositeOperation", "modes[\""+(i)+"\"]");
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.html
new file mode 100644
index 0000000000..08def9a516
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.highlight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.highlight</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'highlight';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.worker.js
new file mode 100644
index 0000000000..800c4605e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.highlight.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.highlight
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'highlight';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.html
new file mode 100644
index 0000000000..f021d40b53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.nullsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.nullsuffix</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'source-over\0';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.worker.js
new file mode 100644
index 0000000000..1c1d5124a3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.nullsuffix.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.nullsuffix
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'source-over\0';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.html
new file mode 100644
index 0000000000..df934336c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'over';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.worker.js
new file mode 100644
index 0000000000..f75a462e93
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.over.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'over';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.html
new file mode 100644
index 0000000000..c649102cc7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.operation.unrecognised</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.operation.unrecognised</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'nonexistent';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.worker.js
new file mode 100644
index 0000000000..23a6630e82
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.operation.unrecognised.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.operation.unrecognised
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'nonexistent';
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.html
new file mode 100644
index 0000000000..9bb03097fc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.clear</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.worker.js
new file mode 100644
index 0000000000..c49ec7a322
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.clear.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.clear
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.html
new file mode 100644
index 0000000000..a5bcda9337
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.copy</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.worker.js
new file mode 100644
index 0000000000..ee4baecbd2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.copy.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.copy
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.html
new file mode 100644
index 0000000000..c5554ff240
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.destination-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.worker.js
new file mode 100644
index 0000000000..8829971c6b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-atop.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.destination-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.html
new file mode 100644
index 0000000000..8e620e2714
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.destination-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.worker.js
new file mode 100644
index 0000000000..fe9e461717
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-in.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.destination-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.html
new file mode 100644
index 0000000000..06da4d3650
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.destination-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.worker.js
new file mode 100644
index 0000000000..05ec2fae16
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-out.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.destination-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.html
new file mode 100644
index 0000000000..e62c3fea70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.destination-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.worker.js
new file mode 100644
index 0000000000..5c171fc282
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.destination-over.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.destination-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,255,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.html
new file mode 100644
index 0000000000..2e09805cc1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.lighter</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,255,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.worker.js
new file mode 100644
index 0000000000..353389221d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.lighter.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.lighter
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,255,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.html
new file mode 100644
index 0000000000..dd36e0e622
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.source-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.worker.js
new file mode 100644
index 0000000000..27e1c253ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-atop.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.source-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.html
new file mode 100644
index 0000000000..83dcc8e523
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.source-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.worker.js
new file mode 100644
index 0000000000..7dfdb07075
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-in.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.source-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.html
new file mode 100644
index 0000000000..3067c44fcd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.source-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.worker.js
new file mode 100644
index 0000000000..8252549267
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-out.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.source-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.html
new file mode 100644
index 0000000000..059655334f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.source-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.worker.js
new file mode 100644
index 0000000000..1c82a95c36
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.source-over.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.source-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 255,255,0,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.html
new file mode 100644
index 0000000000..822c9c70d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.solid.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.solid.xor</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.worker.js
new file mode 100644
index 0000000000..cb098ebab1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.solid.xor.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.solid.xor
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.html
new file mode 100644
index 0000000000..81d781acc7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.clear</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.clear</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.worker.js
new file mode 100644
index 0000000000..8f30463c41
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.clear.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.clear
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'clear';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.html
new file mode 100644
index 0000000000..ab3a97226f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.copy</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,191, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.worker.js
new file mode 100644
index 0000000000..6b9ea9dbcf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.copy.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.copy
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,191, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.html
new file mode 100644
index 0000000000..5e580f5a67
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.destination-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,128,128,191, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.worker.js
new file mode 100644
index 0000000000..3247632e53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-atop.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.destination-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,128,128,191, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.html
new file mode 100644
index 0000000000..9f0ec56357
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.destination-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,96, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.worker.js
new file mode 100644
index 0000000000..c9205230c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-in.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.destination-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,96, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.html
new file mode 100644
index 0000000000..a1abe3eed9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.destination-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.destination-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,32, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.worker.js
new file mode 100644
index 0000000000..1a5409589b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-out.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.destination-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,32, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.html
new file mode 100644
index 0000000000..4f0305f27f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.destination-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.destination-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,146,109,223, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.worker.js
new file mode 100644
index 0000000000..37eb785d67
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.destination-over.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.destination-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,146,109,223, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.html
new file mode 100644
index 0000000000..6a2f5df71f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.lighter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.lighter</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,128,191,255, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.worker.js
new file mode 100644
index 0000000000..3d890affd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.lighter.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.lighter
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,128,191,255, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.html
new file mode 100644
index 0000000000..bac035cea3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.source-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.source-atop</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,64,191,128, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.worker.js
new file mode 100644
index 0000000000..d56ef6e2e4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-atop.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.source-atop
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,64,191,128, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.html
new file mode 100644
index 0000000000..5dd67046ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.source-in</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,96, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.worker.js
new file mode 100644
index 0000000000..58ad13bc5e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-in.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.source-in
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,96, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.html
new file mode 100644
index 0000000000..56b1d4ad46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.source-out</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,96, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.worker.js
new file mode 100644
index 0000000000..62ec895955
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-out.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.source-out
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,255,96, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.html
new file mode 100644
index 0000000000..f038d44a54
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.source-over</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.source-over</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,36,219,223, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.worker.js
new file mode 100644
index 0000000000..494a45f848
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.source-over.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.source-over
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,36,219,223, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.html
new file mode 100644
index 0000000000..bbab8a086c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.transparent.xor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.transparent.xor</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,64,191,128, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.worker.js
new file mode 100644
index 0000000000..4b65667ed8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.transparent.xor.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.transparent.xor
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,64,191,128, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.html
new file mode 100644
index 0000000000..0ff9d851dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.fill.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.fill.copy</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.worker.js
new file mode 100644
index 0000000000..50f3ed0f22
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.copy.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.fill.copy
+// Description:fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.html
new file mode 100644
index 0000000000..2d2f92edb5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.fill.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.fill.destination-atop</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.worker.js
new file mode 100644
index 0000000000..9a84b0894a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-atop.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.fill.destination-atop
+// Description:fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.html
new file mode 100644
index 0000000000..5670b321a6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.fill.destination-in</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.fill.destination-in</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.worker.js
new file mode 100644
index 0000000000..aa24ba97a6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.destination-in.worker.js
@@ -0,0 +1,29 @@
+// META: timeout=long
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.fill.destination-in
+// Description:fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.html
new file mode 100644
index 0000000000..58347442bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.fill.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.fill.source-in</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.worker.js
new file mode 100644
index 0000000000..33e326d1f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-in.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.fill.source-in
+// Description:fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.html
new file mode 100644
index 0000000000..ea44ca4f04
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.fill.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.fill.source-out</h1>
+<p class="desc">fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.worker.js
new file mode 100644
index 0000000000..1d39b364b0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.fill.source-out.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.fill.source-out
+// Description:fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.html
new file mode 100644
index 0000000000..0ecb5ed01d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.image.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.image.copy</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.worker.js
new file mode 100644
index 0000000000..0e56b4f71d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.copy.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.image.copy
+// Description:drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.html
new file mode 100644
index 0000000000..00a4465d0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.image.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.image.destination-atop</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.worker.js
new file mode 100644
index 0000000000..4c4a0a4c95
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-atop.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.image.destination-atop
+// Description:drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.html
new file mode 100644
index 0000000000..f5f8c68c51
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.image.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.image.destination-in</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.worker.js
new file mode 100644
index 0000000000..af1dc50c9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.destination-in.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.image.destination-in
+// Description:drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.html
new file mode 100644
index 0000000000..2e1fe84b60
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.image.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.image.source-in</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.worker.js
new file mode 100644
index 0000000000..490ce4d001
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-in.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.image.source-in
+// Description:drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.html
new file mode 100644
index 0000000000..1f5be066ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.image.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.image.source-out</h1>
+<p class="desc">drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.worker.js
new file mode 100644
index 0000000000..3647e34574
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.image.source-out.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.image.source-out
+// Description:drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ _assertPixelApprox(canvas, 15,15, 0,0,0,0, 5);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.html
new file mode 100644
index 0000000000..10a9960559
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.nocontext.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.nocontext.copy</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.worker.js
new file mode 100644
index 0000000000..1f285eae4c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.copy.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.nocontext.copy
+// Description:drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.html
new file mode 100644
index 0000000000..ead1299cf0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.nocontext.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.nocontext.destination-atop</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.worker.js
new file mode 100644
index 0000000000..a9beb0f27e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-atop.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.nocontext.destination-atop
+// Description:drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.html
new file mode 100644
index 0000000000..0322bfe258
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.nocontext.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.nocontext.destination-in</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.worker.js
new file mode 100644
index 0000000000..e146e2e91a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.destination-in.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.nocontext.destination-in
+// Description:drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.html
new file mode 100644
index 0000000000..0d93a0362e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.nocontext.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.nocontext.source-in</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.worker.js
new file mode 100644
index 0000000000..cce4b54bd5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-in.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.nocontext.source-in
+// Description:drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.html
new file mode 100644
index 0000000000..b6ab8cbda4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.nocontext.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.nocontext.source-out</h1>
+<p class="desc">drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.worker.js
new file mode 100644
index 0000000000..501a84f7e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.nocontext.source-out.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.nocontext.source-out
+// Description:drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.html
new file mode 100644
index 0000000000..c698c2517c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.pattern.copy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.pattern.copy</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.worker.js
new file mode 100644
index 0000000000..a5944be695
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.copy.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.pattern.copy
+// Description:Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.html
new file mode 100644
index 0000000000..887570fad7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.pattern.destination-atop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.pattern.destination-atop</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.worker.js
new file mode 100644
index 0000000000..c34c748059
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-atop.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.pattern.destination-atop
+// Description:Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.html
new file mode 100644
index 0000000000..7aa9e662f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.pattern.destination-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.pattern.destination-in</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.worker.js
new file mode 100644
index 0000000000..10042455a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.destination-in.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.pattern.destination-in
+// Description:Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.html
new file mode 100644
index 0000000000..3830e92f69
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.pattern.source-in</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.pattern.source-in</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.worker.js
new file mode 100644
index 0000000000..c658da8c99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-in.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.pattern.source-in
+// Description:Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.html b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.html
new file mode 100644
index 0000000000..3c202dd556
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.composite.uncovered.pattern.source-out</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.composite.uncovered.pattern.source-out</h1>
+<p class="desc">Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.</p>
+
+
+<script>
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.worker.js b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.worker.js
new file mode 100644
index 0000000000..86baf476fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/compositing/2d.composite.uncovered.pattern.source-out.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.composite.uncovered.pattern.source-out
+// Description:Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,0,0,0, 5);
+ });
+ }).then(t_pass, t_fail);
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.html b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.html
new file mode 100644
index 0000000000..e754e6c6ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.conformance.requirements.basics</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.conformance.requirements.basics</h1>
+<p class="desc">void methods return undefined</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("void methods return undefined");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.save(), undefined, "ctx.save()", "undefined");
+ _assertSame(ctx.restore(), undefined, "ctx.restore()", "undefined");
+ _assertSame(ctx.scale(1, 1), undefined, "ctx.scale(1, 1)", "undefined");
+ _assertSame(ctx.rotate(0), undefined, "ctx.rotate(0)", "undefined");
+ _assertSame(ctx.translate(0, 0), undefined, "ctx.translate(0, 0)", "undefined");
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ _assertSame(ctx.transform(1, 0, 0, 1, 0, 0), undefined, "ctx.transform(1, 0, 0, 1, 0, 0)", "undefined");
+ }
+ if (ctx.setTransform) {
+ _assertSame(ctx.setTransform(1, 0, 0, 1, 0, 0), undefined, "ctx.setTransform(1, 0, 0, 1, 0, 0)", "undefined");
+ _assertSame(ctx.setTransform(), undefined, "ctx.setTransform()", "undefined");
+ }
+ _assertSame(ctx.clearRect(0, 0, 0, 0), undefined, "ctx.clearRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.fillRect(0, 0, 0, 0), undefined, "ctx.fillRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.strokeRect(0, 0, 0, 0), undefined, "ctx.strokeRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.beginPath(), undefined, "ctx.beginPath()", "undefined");
+ _assertSame(ctx.closePath(), undefined, "ctx.closePath()", "undefined");
+ _assertSame(ctx.moveTo(0, 0), undefined, "ctx.moveTo(0, 0)", "undefined");
+ _assertSame(ctx.lineTo(0, 0), undefined, "ctx.lineTo(0, 0)", "undefined");
+ _assertSame(ctx.quadraticCurveTo(0, 0, 0, 0), undefined, "ctx.quadraticCurveTo(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.bezierCurveTo(0, 0, 0, 0, 0, 0), undefined, "ctx.bezierCurveTo(0, 0, 0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.arcTo(0, 0, 0, 0, 1), undefined, "ctx.arcTo(0, 0, 0, 0, 1)", "undefined");
+ _assertSame(ctx.rect(0, 0, 0, 0), undefined, "ctx.rect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.arc(0, 0, 1, 0, 0, true), undefined, "ctx.arc(0, 0, 1, 0, 0, true)", "undefined");
+ _assertSame(ctx.fill(), undefined, "ctx.fill()", "undefined");
+ _assertSame(ctx.stroke(), undefined, "ctx.stroke()", "undefined");
+ _assertSame(ctx.clip(), undefined, "ctx.clip()", "undefined");
+ if (ctx.fillText) {
+ _assertSame(ctx.fillText('test', 0, 0), undefined, "ctx.fillText('test', 0, 0)", "undefined");
+ _assertSame(ctx.strokeText('test', 0, 0), undefined, "ctx.strokeText('test', 0, 0)", "undefined");
+ }
+ if (ctx.putImageData) {
+ _assertSame(ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0), undefined, "ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0)", "undefined");
+ }
+ _assertSame(ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white'), undefined, "ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white')", "undefined");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.worker.js b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.worker.js
new file mode 100644
index 0000000000..b16a39fd3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.basics.worker.js
@@ -0,0 +1,57 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.conformance.requirements.basics
+// Description:void methods return undefined
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("void methods return undefined");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.save(), undefined, "ctx.save()", "undefined");
+ _assertSame(ctx.restore(), undefined, "ctx.restore()", "undefined");
+ _assertSame(ctx.scale(1, 1), undefined, "ctx.scale(1, 1)", "undefined");
+ _assertSame(ctx.rotate(0), undefined, "ctx.rotate(0)", "undefined");
+ _assertSame(ctx.translate(0, 0), undefined, "ctx.translate(0, 0)", "undefined");
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ _assertSame(ctx.transform(1, 0, 0, 1, 0, 0), undefined, "ctx.transform(1, 0, 0, 1, 0, 0)", "undefined");
+ }
+ if (ctx.setTransform) {
+ _assertSame(ctx.setTransform(1, 0, 0, 1, 0, 0), undefined, "ctx.setTransform(1, 0, 0, 1, 0, 0)", "undefined");
+ _assertSame(ctx.setTransform(), undefined, "ctx.setTransform()", "undefined");
+ }
+ _assertSame(ctx.clearRect(0, 0, 0, 0), undefined, "ctx.clearRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.fillRect(0, 0, 0, 0), undefined, "ctx.fillRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.strokeRect(0, 0, 0, 0), undefined, "ctx.strokeRect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.beginPath(), undefined, "ctx.beginPath()", "undefined");
+ _assertSame(ctx.closePath(), undefined, "ctx.closePath()", "undefined");
+ _assertSame(ctx.moveTo(0, 0), undefined, "ctx.moveTo(0, 0)", "undefined");
+ _assertSame(ctx.lineTo(0, 0), undefined, "ctx.lineTo(0, 0)", "undefined");
+ _assertSame(ctx.quadraticCurveTo(0, 0, 0, 0), undefined, "ctx.quadraticCurveTo(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.bezierCurveTo(0, 0, 0, 0, 0, 0), undefined, "ctx.bezierCurveTo(0, 0, 0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.arcTo(0, 0, 0, 0, 1), undefined, "ctx.arcTo(0, 0, 0, 0, 1)", "undefined");
+ _assertSame(ctx.rect(0, 0, 0, 0), undefined, "ctx.rect(0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.arc(0, 0, 1, 0, 0, true), undefined, "ctx.arc(0, 0, 1, 0, 0, true)", "undefined");
+ _assertSame(ctx.fill(), undefined, "ctx.fill()", "undefined");
+ _assertSame(ctx.stroke(), undefined, "ctx.stroke()", "undefined");
+ _assertSame(ctx.clip(), undefined, "ctx.clip()", "undefined");
+ if (ctx.fillText) {
+ _assertSame(ctx.fillText('test', 0, 0), undefined, "ctx.fillText('test', 0, 0)", "undefined");
+ _assertSame(ctx.strokeText('test', 0, 0), undefined, "ctx.strokeText('test', 0, 0)", "undefined");
+ }
+ if (ctx.putImageData) {
+ _assertSame(ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0), undefined, "ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0)", "undefined");
+ }
+ _assertSame(ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0), undefined, "ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0)", "undefined");
+ _assertSame(ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white'), undefined, "ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white')", "undefined");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.html b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.html
new file mode 100644
index 0000000000..fe28a68e90
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.conformance.requirements.missingargs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.conformance.requirements.missingargs</h1>
+<p class="desc">Missing arguments cause TypeError</p>
+
+
+<script>
+var t = async_test("Missing arguments cause TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.scale(); });
+ assert_throws_js(TypeError, function() { ctx.scale(1); });
+ assert_throws_js(TypeError, function() { ctx.rotate(); });
+ assert_throws_js(TypeError, function() { ctx.translate(); });
+ assert_throws_js(TypeError, function() { ctx.translate(0); });
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ assert_throws_js(TypeError, function() { ctx.transform(); });
+ assert_throws_js(TypeError, function() { ctx.transform(1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1, 0); });
+ }
+ if (ctx.setTransform) {
+ assert_throws_js(TypeError, function() { ctx.setTransform(1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1, 0); });
+ }
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createPattern(canvas); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.moveTo(); });
+ assert_throws_js(TypeError, function() { ctx.moveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.lineTo(); });
+ assert_throws_js(TypeError, function() { ctx.lineTo(0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.rect(); });
+ assert_throws_js(TypeError, function() { ctx.rect(0); });
+ assert_throws_js(TypeError, function() { ctx.rect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.rect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arc(); });
+ assert_throws_js(TypeError, function() { ctx.arc(0); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1, 0); });
+ // (6th argument to arc is optional)
+ if (ctx.isPointInPath) {
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(0); });
+ }
+ if (ctx.drawFocusRing) {
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas, 0); });
+ }
+ if (ctx.fillText) {
+ assert_throws_js(TypeError, function() { ctx.fillText(); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test'); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeText(); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test'); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.measureText(); });
+ }
+ assert_throws_js(TypeError, function() { ctx.drawImage(); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(canvas, 0); });
+ // TODO: n >= 3 args on drawImage could be either a valid overload,
+ // or too few for another overload, or too many for another
+ // overload - what should happen?
+ if (ctx.createImageData) {
+ assert_throws_js(TypeError, function() { ctx.createImageData(); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(1); });
+ }
+ if (ctx.getImageData) {
+ assert_throws_js(TypeError, function() { ctx.getImageData(); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0, 1); });
+ }
+ if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ assert_throws_js(TypeError, function() { ctx.putImageData(); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0); });
+ }
+ var g = ctx.createLinearGradient(0, 0, 0, 0);
+ assert_throws_js(TypeError, function() { g.addColorStop(); });
+ assert_throws_js(TypeError, function() { g.addColorStop(0); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.worker.js b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.worker.js
new file mode 100644
index 0000000000..f249fcb881
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/conformance-requirements/2d.conformance.requirements.missingargs.worker.js
@@ -0,0 +1,136 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.conformance.requirements.missingargs
+// Description:Missing arguments cause TypeError
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Missing arguments cause TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.scale(); });
+ assert_throws_js(TypeError, function() { ctx.scale(1); });
+ assert_throws_js(TypeError, function() { ctx.rotate(); });
+ assert_throws_js(TypeError, function() { ctx.translate(); });
+ assert_throws_js(TypeError, function() { ctx.translate(0); });
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ assert_throws_js(TypeError, function() { ctx.transform(); });
+ assert_throws_js(TypeError, function() { ctx.transform(1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.transform(1, 0, 0, 1, 0); });
+ }
+ if (ctx.setTransform) {
+ assert_throws_js(TypeError, function() { ctx.setTransform(1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.setTransform(1, 0, 0, 1, 0); });
+ }
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.createPattern(canvas); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.clearRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.fillRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeRect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.moveTo(); });
+ assert_throws_js(TypeError, function() { ctx.moveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.lineTo(); });
+ assert_throws_js(TypeError, function() { ctx.lineTo(0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.quadraticCurveTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.bezierCurveTo(0, 0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arcTo(0, 0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.rect(); });
+ assert_throws_js(TypeError, function() { ctx.rect(0); });
+ assert_throws_js(TypeError, function() { ctx.rect(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.rect(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arc(); });
+ assert_throws_js(TypeError, function() { ctx.arc(0); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.arc(0, 0, 1, 0); });
+ // (6th argument to arc is optional)
+ if (ctx.isPointInPath) {
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(0); });
+ }
+ if (ctx.drawFocusRing) {
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawFocusRing(canvas, 0); });
+ }
+ if (ctx.fillText) {
+ assert_throws_js(TypeError, function() { ctx.fillText(); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test'); });
+ assert_throws_js(TypeError, function() { ctx.fillText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.strokeText(); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test'); });
+ assert_throws_js(TypeError, function() { ctx.strokeText('test', 0); });
+ assert_throws_js(TypeError, function() { ctx.measureText(); });
+ }
+ assert_throws_js(TypeError, function() { ctx.drawImage(); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(canvas); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(canvas, 0); });
+ // TODO: n >= 3 args on drawImage could be either a valid overload,
+ // or too few for another overload, or too many for another
+ // overload - what should happen?
+ if (ctx.createImageData) {
+ assert_throws_js(TypeError, function() { ctx.createImageData(); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(1); });
+ }
+ if (ctx.getImageData) {
+ assert_throws_js(TypeError, function() { ctx.getImageData(); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(0, 0, 1); });
+ }
+ if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ assert_throws_js(TypeError, function() { ctx.putImageData(); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0); });
+ }
+ var g = ctx.createLinearGradient(0, 0, 0, 0);
+ assert_throws_js(TypeError, function() { g.addColorStop(); });
+ assert_throws_js(TypeError, function() { g.addColorStop(0); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.html
new file mode 100644
index 0000000000..7f1f66654d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.3arg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.3arg</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0);
+ ctx.drawImage(bitmap_red, -100, 0);
+ ctx.drawImage(bitmap_red, 100, 0);
+ ctx.drawImage(bitmap_red, 0, -50);
+ ctx.drawImage(bitmap_red, 0, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.worker.js
new file mode 100644
index 0000000000..b2f860bc60
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.3arg.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.3arg
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0);
+ ctx.drawImage(bitmap_red, -100, 0);
+ ctx.drawImage(bitmap_red, 100, 0);
+ ctx.drawImage(bitmap_red, 0, -50);
+ ctx.drawImage(bitmap_red, 0, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.html
new file mode 100644
index 0000000000..f7bf0568c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.5arg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.5arg</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.worker.js
new file mode 100644
index 0000000000..f725acf011
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.5arg.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.5arg
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html
new file mode 100644
index 0000000000..47e442e23e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.9arg.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.9arg.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.worker.js
new file mode 100644
index 0000000000..b2d6f7d860
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.basic.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.9arg.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html
new file mode 100644
index 0000000000..5e0f3f1088
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.9arg.destpos</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.9arg.destpos</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, -100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -50, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.worker.js
new file mode 100644
index 0000000000..380d526f9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destpos.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.9arg.destpos
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, -100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -50, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html
new file mode 100644
index 0000000000..93b587a44f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.9arg.destsize</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.9arg.destsize</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 1, 1, 1, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, -50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -25, 100, 25);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 25);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.worker.js
new file mode 100644
index 0000000000..76e3e8baaf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.destsize.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.9arg.destsize
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 1, 1, 1, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, -50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -25, 100, 25);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 25);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html
new file mode 100644
index 0000000000..e822ab43fa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.9arg.sourcepos</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.9arg.sourcepos</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 140, 20, 100, 50, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.worker.js
new file mode 100644
index 0000000000..d3525435fa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcepos.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.9arg.sourcepos
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 140, 20, 100, 50, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html
new file mode 100644
index 0000000000..b99ca58768
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.9arg.sourcesize</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.9arg.sourcesize</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 0, 256, 256, 0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 51, 26);
+ ctx.fillRect(49, 24, 51, 26);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 20,20, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,20, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 20,30, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,30, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.worker.js
new file mode 100644
index 0000000000..aa15efb705
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.9arg.sourcesize.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.9arg.sourcesize
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 0, 256, 256, 0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 51, 26);
+ ctx.fillRect(49, 24, 51, 26);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 20,20, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,20, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 20,30, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,30, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.html
new file mode 100644
index 0000000000..a95f3ece7a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.alpha</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.worker.js
new file mode 100644
index 0000000000..958a2431b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.alpha.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.alpha
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.html
new file mode 100644
index 0000000000..a2afa05f01
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.broken</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.broken</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response = await fetch('/images/broken.png');
+ const blob = await response.blob();
+
+ await promise_rejects_dom(t, 'InvalidStateError', createImageBitmap(blob), 'The source image could not be decoded.');
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.worker.js
new file mode 100644
index 0000000000..dc695b5459
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.broken.worker.js
@@ -0,0 +1,20 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.broken
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response = await fetch('/images/broken.png');
+ const blob = await response.blob();
+
+ await promise_rejects_dom(t, 'InvalidStateError', createImageBitmap(blob), 'The source image could not be decoded.');
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.html
new file mode 100644
index 0000000000..e5eeedea6e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.canvas</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.worker.js
new file mode 100644
index 0000000000..1f18cd7723
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.canvas.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.canvas
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.html
new file mode 100644
index 0000000000..a828039b7b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.clip</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.worker.js
new file mode 100644
index 0000000000..fea2a7bac7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.clip.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.clip
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.html
new file mode 100644
index 0000000000..b32b5a12ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.composite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.composite</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.worker.js
new file mode 100644
index 0000000000..0b17673b68
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.composite.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.composite
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.html
new file mode 100644
index 0000000000..e201082e35
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.floatsource</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.floatsource</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.worker.js
new file mode 100644
index 0000000000..1efc17d04d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.floatsource.worker.js
@@ -0,0 +1,21 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.floatsource
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.html
new file mode 100644
index 0000000000..3e43a772c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.negativedest</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.negativedest</h1>
+<p class="desc">Negative destination width/height represents the correct rectangle</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, 50, 50, 0, 50, 50, -50);
+ ctx.drawImage(bitmap, 100, 128, 50, -50, 100, 50, -50, -50);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Negative destination width/height represents the correct rectangle");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.worker.js
new file mode 100644
index 0000000000..ce5cf5efad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedest.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.negativedest
+// Description:Negative destination width/height represents the correct rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, 50, 50, 0, 50, 50, -50);
+ ctx.drawImage(bitmap, 100, 128, 50, -50, 100, 50, -50, -50);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Negative destination width/height represents the correct rectangle");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.html
new file mode 100644
index 0000000000..347b634cfd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.negativedir</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.negativedir</h1>
+<p class="desc">Negative dimensions do not affect the direction of the image</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 178, 50, -100, 0, 0, 50, 100);
+ ctx.drawImage(bitmap, 0, 78, 50, 100, 50, 100, 50, -100);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Negative dimensions do not affect the direction of the image");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.worker.js
new file mode 100644
index 0000000000..c82b9ba1be
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativedir.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.negativedir
+// Description:Negative dimensions do not affect the direction of the image
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 178, 50, -100, 0, 0, 50, 100);
+ ctx.drawImage(bitmap, 0, 78, 50, 100, 50, 100, 50, -100);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Negative dimensions do not affect the direction of the image");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.html
new file mode 100644
index 0000000000..3e18725720
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.negativesource</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.negativesource</h1>
+<p class="desc">Negative source width/height represents the correct rectangle</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, -100, 50, 0, 0, 50, 50);
+ ctx.drawImage(bitmap, 100, 128, -100, -50, 50, 0, 50, 50);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Negative source width/height represents the correct rectangle");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.worker.js
new file mode 100644
index 0000000000..f92d15774d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.negativesource.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.negativesource
+// Description:Negative source width/height represents the correct rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, -100, 50, 0, 0, 50, 50);
+ ctx.drawImage(bitmap, 100, 128, -100, -50, 50, 0, 50, 50);
+ _assertPixelApprox(canvas, 1,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 48,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,1, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 51,48, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Negative source width/height represents the correct rectangle");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html
new file mode 100644
index 0000000000..93dccd3d4e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.html
@@ -0,0 +1,328 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.nonfinite</h1>
+<p class="desc">drawImage() with Infinity/NaN is ignored</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, Infinity, 0);
+ ctx.drawImage(bitmap, -Infinity, 0);
+ ctx.drawImage(bitmap, NaN, 0);
+ ctx.drawImage(bitmap, 0, Infinity);
+ ctx.drawImage(bitmap, 0, -Infinity);
+ ctx.drawImage(bitmap, 0, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, -Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, NaN, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, -Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, NaN, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, -Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, NaN, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, -Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, -Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, NaN, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, -Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, NaN, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, -Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, NaN, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, -Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, NaN, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, -Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, NaN, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, -Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, NaN, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, -Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, NaN, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, -Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+}, "drawImage() with Infinity/NaN is ignored");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.worker.js
new file mode 100644
index 0000000000..a56f09e0b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nonfinite.worker.js
@@ -0,0 +1,324 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.nonfinite
+// Description:drawImage() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, Infinity, 0);
+ ctx.drawImage(bitmap, -Infinity, 0);
+ ctx.drawImage(bitmap, NaN, 0);
+ ctx.drawImage(bitmap, 0, Infinity);
+ ctx.drawImage(bitmap, 0, -Infinity);
+ ctx.drawImage(bitmap, 0, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, -Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, NaN, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, -Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, NaN, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, -Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, NaN, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, -Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, -Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, NaN, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, -Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, NaN, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, -Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, NaN, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, -Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, NaN, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, -Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, NaN, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, -Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, NaN, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, -Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, NaN, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, -Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, NaN);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, Infinity, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+}, "drawImage() with Infinity/NaN is ignored");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.html
new file mode 100644
index 0000000000..1182baec3b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.nowrap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.nowrap</h1>
+<p class="desc">Stretched images do not get pixels wrapping around the edges</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, -1950, 0, 2000, 50);
+ _assertPixelApprox(canvas, 45,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 55,25, 0,255,0,255, 2);
+
+}, "Stretched images do not get pixels wrapping around the edges");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.worker.js
new file mode 100644
index 0000000000..47a77834c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.nowrap.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.nowrap
+// Description:Stretched images do not get pixels wrapping around the edges
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, -1950, 0, 2000, 50);
+ _assertPixelApprox(canvas, 45,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 55,25, 0,255,0,255, 2);
+ t.done();
+}, "Stretched images do not get pixels wrapping around the edges");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.html
new file mode 100644
index 0000000000..7a8338b353
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.null</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.drawImage(null, 0, 0); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.worker.js
new file mode 100644
index 0000000000..329abd2221
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.null.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.null
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.drawImage(null, 0, 0); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.html
new file mode 100644
index 0000000000..063353c11f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.path</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ ctx.fill();
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.worker.js
new file mode 100644
index 0000000000..3259ff0258
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.path.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.path
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ ctx.fill();
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.html
new file mode 100644
index 0000000000..c5e51c2772
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.self.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.self.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.drawImage(canvas, 50, 0);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.worker.js
new file mode 100644
index 0000000000..a9af88d13a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.1.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.self.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.drawImage(canvas, 50, 0);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.html
new file mode 100644
index 0000000000..ac67476966
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.self.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.self.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 1, 100, 49);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 1);
+ ctx.drawImage(canvas, 0, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 2);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.worker.js
new file mode 100644
index 0000000000..802d2d8c52
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.self.2.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.self.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 1, 100, 49);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 1);
+ ctx.drawImage(canvas, 0, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 2);
+
+ _assertPixelApprox(canvas, 0,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,0, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 0,49, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 99,49, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.svg.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.svg.html
new file mode 100644
index 0000000000..c2ebd265cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.svg.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.svg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.svg</h1>
+<p class="desc">drawImage() of an SVG image</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const img = new Image();
+ const imageLoadPromise = new Promise((resolve, reject) => {
+ img.onload = () => resolve();
+ img.onerror = (err) => reject(err);
+ });
+ img.src = '/images/green.svg';
+ await imageLoadPromise;
+
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50, 25, 0, 255, 0, 255, 2);
+
+}, "drawImage() of an SVG image");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.html
new file mode 100644
index 0000000000..ca148c1a68
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.transform</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(100, 0);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.worker.js
new file mode 100644
index 0000000000..4a4cd07be9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.transform.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.transform
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(100, 0);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
new file mode 100644
index 0000000000..96906e8fc3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.wrongtype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.wrongtype</h1>
+<p class="desc">Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError</p>
+
+
+<script>
+var t = async_test("Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.drawImage(undefined, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.drawImage("", 0, 0); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.worker.js
new file mode 100644
index 0000000000..176e418d64
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.wrongtype.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.wrongtype
+// Description:Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.drawImage(undefined, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.drawImage(0, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.drawImage("", 0, 0); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html
new file mode 100644
index 0000000000..a30c300730
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.zerocanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.zerocanvas</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(0, 10);
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(offscreenCanvas2, 0, 0); });
+
+ offscreenCanvas2.width = 10;
+ offscreenCanvas2.height = 0;
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(offscreenCanvas2, 0, 0); });
+
+ offscreenCanvas2.width = 0;
+ offscreenCanvas2.height = 0;
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(offscreenCanvas2, 0, 0); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.worker.js
new file mode 100644
index 0000000000..41346ad328
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerocanvas.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.zerocanvas
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(0, 10);
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(offscreenCanvas2, 0, 0); });
+
+ offscreenCanvas2.width = 10;
+ offscreenCanvas2.height = 0;
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(offscreenCanvas2, 0, 0); });
+
+ offscreenCanvas2.width = 0;
+ offscreenCanvas2.height = 0;
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(offscreenCanvas2, 0, 0); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.html
new file mode 100644
index 0000000000..0239c5356d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.zerosource</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.zerosource</h1>
+<p class="desc">drawImage with zero-sized source rectangle draws nothing without exception</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10, 10, 0, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 1, 0, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 0, 0, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+
+}, "drawImage with zero-sized source rectangle draws nothing without exception");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html
new file mode 100644
index 0000000000..77182242d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.drawImage.zerosource.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.drawImage.zerosource.image</h1>
+<p class="desc">drawImage with zero-sized source rectangle from image draws nothing without exception</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ function loadImage(src) {
+ return new Promise((resolve, reject) => {
+ const img = new Image();
+ img.onload = () => resolve(img);
+ img.onerror = (err) => reject(err);
+ img.src = src;
+ });
+ }
+ const img1 = await loadImage('/images/red-zerowidth.svg');
+ const img2 = await loadImage('/images/red-zeroheight.svg');
+ const img3 = await loadImage('/images/red-zerosize.svg');
+
+ ctx.drawImage(img1, 0, 0, 100, 50);
+ ctx.drawImage(img2, 0, 0, 100, 50);
+ ctx.drawImage(img3, 0, 0, 100, 50);
+ _assertPixel(canvas, 50, 25, 0, 255, 0, 255);
+
+}, "drawImage with zero-sized source rectangle from image draws nothing without exception");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.worker.js
new file mode 100644
index 0000000000..a80bfff562
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-images-to-the-canvas/2d.drawImage.zerosource.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.drawImage.zerosource
+// Description:drawImage with zero-sized source rectangle draws nothing without exception
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10, 10, 0, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 1, 0, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 0, 0, 0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+}, "drawImage with zero-sized source rectangle draws nothing without exception");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html
new file mode 100644
index 0000000000..02a9cb37ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.basic</h1>
+<p class="desc">clearRect clears to transparent black</p>
+
+
+<script>
+var t = async_test("clearRect clears to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.worker.js
new file mode 100644
index 0000000000..8f3a7e46de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.basic.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.basic
+// Description:clearRect clears to transparent black
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect clears to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html
new file mode 100644
index 0000000000..2f0f171601
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.clip</h1>
+<p class="desc">clearRect is affected by clipping regions</p>
+
+
+<script>
+var t = async_test("clearRect is affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.worker.js
new file mode 100644
index 0000000000..3d3caedbb1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.clip.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.clip
+// Description:clearRect is affected by clipping regions
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect is affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html
new file mode 100644
index 0000000000..45875c5270
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.globalalpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.globalalpha</h1>
+<p class="desc">clearRect is not affected by globalAlpha</p>
+
+
+<script>
+var t = async_test("clearRect is not affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.1;
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.worker.js
new file mode 100644
index 0000000000..1b07b66cb3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalalpha.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.globalalpha
+// Description:clearRect is not affected by globalAlpha
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect is not affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.1;
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html
new file mode 100644
index 0000000000..b57be641ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.globalcomposite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.globalcomposite</h1>
+<p class="desc">clearRect is not affected by globalCompositeOperation</p>
+
+
+<script>
+var t = async_test("clearRect is not affected by globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.worker.js
new file mode 100644
index 0000000000..e8c1c9b27c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.globalcomposite.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.globalcomposite
+// Description:clearRect is not affected by globalCompositeOperation
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect is not affected by globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.clearRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html
new file mode 100644
index 0000000000..12126dfe87
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.negative</h1>
+<p class="desc">clearRect of negative sizes works</p>
+
+
+<script>
+var t = async_test("clearRect of negative sizes works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 50, 25);
+ ctx.clearRect(100, 0, -50, 25);
+ ctx.clearRect(0, 50, 50, -25);
+ ctx.clearRect(100, 50, -50, -25);
+ _assertPixel(canvas, 25,12, 0,0,0,0);
+ _assertPixel(canvas, 75,12, 0,0,0,0);
+ _assertPixel(canvas, 25,37, 0,0,0,0);
+ _assertPixel(canvas, 75,37, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.worker.js
new file mode 100644
index 0000000000..62846aec8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.negative.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.negative
+// Description:clearRect of negative sizes works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect of negative sizes works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 50, 25);
+ ctx.clearRect(100, 0, -50, 25);
+ ctx.clearRect(0, 50, 50, -25);
+ ctx.clearRect(100, 50, -50, -25);
+ _assertPixel(canvas, 25,12, 0,0,0,0);
+ _assertPixel(canvas, 75,12, 0,0,0,0);
+ _assertPixel(canvas, 25,37, 0,0,0,0);
+ _assertPixel(canvas, 75,37, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html
new file mode 100644
index 0000000000..3327834146
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.nonfinite</h1>
+<p class="desc">clearRect() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("clearRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(Infinity, 0, 100, 50);
+ ctx.clearRect(-Infinity, 0, 100, 50);
+ ctx.clearRect(NaN, 0, 100, 50);
+ ctx.clearRect(0, Infinity, 100, 50);
+ ctx.clearRect(0, -Infinity, 100, 50);
+ ctx.clearRect(0, NaN, 100, 50);
+ ctx.clearRect(0, 0, Infinity, 50);
+ ctx.clearRect(0, 0, -Infinity, 50);
+ ctx.clearRect(0, 0, NaN, 50);
+ ctx.clearRect(0, 0, 100, Infinity);
+ ctx.clearRect(0, 0, 100, -Infinity);
+ ctx.clearRect(0, 0, 100, NaN);
+ ctx.clearRect(Infinity, Infinity, 100, 50);
+ ctx.clearRect(Infinity, Infinity, Infinity, 50);
+ ctx.clearRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.clearRect(Infinity, Infinity, 100, Infinity);
+ ctx.clearRect(Infinity, 0, Infinity, 50);
+ ctx.clearRect(Infinity, 0, Infinity, Infinity);
+ ctx.clearRect(Infinity, 0, 100, Infinity);
+ ctx.clearRect(0, Infinity, Infinity, 50);
+ ctx.clearRect(0, Infinity, Infinity, Infinity);
+ ctx.clearRect(0, Infinity, 100, Infinity);
+ ctx.clearRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.worker.js
new file mode 100644
index 0000000000..e2525df3be
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.nonfinite.worker.js
@@ -0,0 +1,47 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.nonfinite
+// Description:clearRect() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(Infinity, 0, 100, 50);
+ ctx.clearRect(-Infinity, 0, 100, 50);
+ ctx.clearRect(NaN, 0, 100, 50);
+ ctx.clearRect(0, Infinity, 100, 50);
+ ctx.clearRect(0, -Infinity, 100, 50);
+ ctx.clearRect(0, NaN, 100, 50);
+ ctx.clearRect(0, 0, Infinity, 50);
+ ctx.clearRect(0, 0, -Infinity, 50);
+ ctx.clearRect(0, 0, NaN, 50);
+ ctx.clearRect(0, 0, 100, Infinity);
+ ctx.clearRect(0, 0, 100, -Infinity);
+ ctx.clearRect(0, 0, 100, NaN);
+ ctx.clearRect(Infinity, Infinity, 100, 50);
+ ctx.clearRect(Infinity, Infinity, Infinity, 50);
+ ctx.clearRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.clearRect(Infinity, Infinity, 100, Infinity);
+ ctx.clearRect(Infinity, 0, Infinity, 50);
+ ctx.clearRect(Infinity, 0, Infinity, Infinity);
+ ctx.clearRect(Infinity, 0, 100, Infinity);
+ ctx.clearRect(0, Infinity, Infinity, 50);
+ ctx.clearRect(0, Infinity, Infinity, Infinity);
+ ctx.clearRect(0, Infinity, 100, Infinity);
+ ctx.clearRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.html
new file mode 100644
index 0000000000..25ad954d06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.path</h1>
+<p class="desc">clearRect does not affect the current path</p>
+
+
+<script>
+var t = async_test("clearRect does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 16, 16);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.worker.js
new file mode 100644
index 0000000000..40f51f9f0e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.path.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.path
+// Description:clearRect does not affect the current path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 16, 16);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html
new file mode 100644
index 0000000000..3b3e41c19c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.shadow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.shadow</h1>
+<p class="desc">clearRect does not draw shadows</p>
+
+
+<script>
+var t = async_test("clearRect does not draw shadows");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.clearRect(0, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.worker.js
new file mode 100644
index 0000000000..a1ec8ac7ae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.shadow.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.shadow
+// Description:clearRect does not draw shadows
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect does not draw shadows");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.clearRect(0, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html
new file mode 100644
index 0000000000..8208b6f657
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.transform</h1>
+<p class="desc">clearRect is affected by transforms</p>
+
+
+<script>
+var t = async_test("clearRect is affected by transforms");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.clearRect(0, -5, 10, 5);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.worker.js
new file mode 100644
index 0000000000..f176f3da8a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.transform.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.transform
+// Description:clearRect is affected by transforms
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect is affected by transforms");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.clearRect(0, -5, 10, 5);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html
new file mode 100644
index 0000000000..461c318d24
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.clearRect.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.clearRect.zero</h1>
+<p class="desc">clearRect of zero pixels has no effect</p>
+
+
+<script>
+var t = async_test("clearRect of zero pixels has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 0);
+ ctx.clearRect(0, 0, 0, 50);
+ ctx.clearRect(0, 0, 0, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.worker.js
new file mode 100644
index 0000000000..b6f42551a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.clearRect.zero.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.clearRect.zero
+// Description:clearRect of zero pixels has no effect
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("clearRect of zero pixels has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 0);
+ ctx.clearRect(0, 0, 0, 50);
+ ctx.clearRect(0, 0, 0, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html
new file mode 100644
index 0000000000..3e65472b83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.basic</h1>
+<p class="desc">fillRect works</p>
+
+
+<script>
+var t = async_test("fillRect works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.worker.js
new file mode 100644
index 0000000000..69918278e4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.basic.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.basic
+// Description:fillRect works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html
new file mode 100644
index 0000000000..3b26960e24
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.clip</h1>
+<p class="desc">fillRect is affected by clipping regions</p>
+
+
+<script>
+var t = async_test("fillRect is affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.worker.js
new file mode 100644
index 0000000000..890b31e342
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.clip.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.clip
+// Description:fillRect is affected by clipping regions
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect is affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html
new file mode 100644
index 0000000000..2a1942811f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.negative</h1>
+<p class="desc">fillRect of negative sizes works</p>
+
+
+<script>
+var t = async_test("fillRect of negative sizes works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillRect(100, 0, -50, 25);
+ ctx.fillRect(0, 50, 50, -25);
+ ctx.fillRect(100, 50, -50, -25);
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.worker.js
new file mode 100644
index 0000000000..5df1652331
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.negative.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.negative
+// Description:fillRect of negative sizes works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect of negative sizes works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillRect(100, 0, -50, 25);
+ ctx.fillRect(0, 50, 50, -25);
+ ctx.fillRect(100, 50, -50, -25);
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html
new file mode 100644
index 0000000000..e44a9d4b78
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.nonfinite</h1>
+<p class="desc">fillRect() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("fillRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(Infinity, 0, 100, 50);
+ ctx.fillRect(-Infinity, 0, 100, 50);
+ ctx.fillRect(NaN, 0, 100, 50);
+ ctx.fillRect(0, Infinity, 100, 50);
+ ctx.fillRect(0, -Infinity, 100, 50);
+ ctx.fillRect(0, NaN, 100, 50);
+ ctx.fillRect(0, 0, Infinity, 50);
+ ctx.fillRect(0, 0, -Infinity, 50);
+ ctx.fillRect(0, 0, NaN, 50);
+ ctx.fillRect(0, 0, 100, Infinity);
+ ctx.fillRect(0, 0, 100, -Infinity);
+ ctx.fillRect(0, 0, 100, NaN);
+ ctx.fillRect(Infinity, Infinity, 100, 50);
+ ctx.fillRect(Infinity, Infinity, Infinity, 50);
+ ctx.fillRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.fillRect(Infinity, Infinity, 100, Infinity);
+ ctx.fillRect(Infinity, 0, Infinity, 50);
+ ctx.fillRect(Infinity, 0, Infinity, Infinity);
+ ctx.fillRect(Infinity, 0, 100, Infinity);
+ ctx.fillRect(0, Infinity, Infinity, 50);
+ ctx.fillRect(0, Infinity, Infinity, Infinity);
+ ctx.fillRect(0, Infinity, 100, Infinity);
+ ctx.fillRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.worker.js
new file mode 100644
index 0000000000..bc0170918c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.nonfinite.worker.js
@@ -0,0 +1,48 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.nonfinite
+// Description:fillRect() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(Infinity, 0, 100, 50);
+ ctx.fillRect(-Infinity, 0, 100, 50);
+ ctx.fillRect(NaN, 0, 100, 50);
+ ctx.fillRect(0, Infinity, 100, 50);
+ ctx.fillRect(0, -Infinity, 100, 50);
+ ctx.fillRect(0, NaN, 100, 50);
+ ctx.fillRect(0, 0, Infinity, 50);
+ ctx.fillRect(0, 0, -Infinity, 50);
+ ctx.fillRect(0, 0, NaN, 50);
+ ctx.fillRect(0, 0, 100, Infinity);
+ ctx.fillRect(0, 0, 100, -Infinity);
+ ctx.fillRect(0, 0, 100, NaN);
+ ctx.fillRect(Infinity, Infinity, 100, 50);
+ ctx.fillRect(Infinity, Infinity, Infinity, 50);
+ ctx.fillRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.fillRect(Infinity, Infinity, 100, Infinity);
+ ctx.fillRect(Infinity, 0, Infinity, 50);
+ ctx.fillRect(Infinity, 0, Infinity, Infinity);
+ ctx.fillRect(Infinity, 0, 100, Infinity);
+ ctx.fillRect(0, Infinity, Infinity, 50);
+ ctx.fillRect(0, Infinity, Infinity, Infinity);
+ ctx.fillRect(0, Infinity, 100, Infinity);
+ ctx.fillRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.html
new file mode 100644
index 0000000000..bcf7ee5a97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.path</h1>
+<p class="desc">fillRect does not affect the current path</p>
+
+
+<script>
+var t = async_test("fillRect does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.worker.js
new file mode 100644
index 0000000000..ddbfc4a96d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.path.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.path
+// Description:fillRect does not affect the current path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html
new file mode 100644
index 0000000000..8a8e38070c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.shadow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.shadow</h1>
+<p class="desc">fillRect draws shadows</p>
+
+
+<script>
+var t = async_test("fillRect draws shadows");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.worker.js
new file mode 100644
index 0000000000..ff4ef0ca2d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.shadow.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.shadow
+// Description:fillRect draws shadows
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect draws shadows");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html
new file mode 100644
index 0000000000..19cb6ac77a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.transform</h1>
+<p class="desc">fillRect is affected by transforms</p>
+
+
+<script>
+var t = async_test("fillRect is affected by transforms");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -5, 10, 5);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.worker.js
new file mode 100644
index 0000000000..a7f328955b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.transform.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.transform
+// Description:fillRect is affected by transforms
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect is affected by transforms");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -5, 10, 5);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html
new file mode 100644
index 0000000000..3ec78ba18a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillRect.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillRect.zero</h1>
+<p class="desc">fillRect of zero pixels has no effect</p>
+
+
+<script>
+var t = async_test("fillRect of zero pixels has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 0);
+ ctx.fillRect(0, 0, 0, 50);
+ ctx.fillRect(0, 0, 0, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.worker.js
new file mode 100644
index 0000000000..a310d3ff28
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.fillRect.zero.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillRect.zero
+// Description:fillRect of zero pixels has no effect
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect of zero pixels has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 0);
+ ctx.fillRect(0, 0, 0, 50);
+ ctx.fillRect(0, 0, 0, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html
new file mode 100644
index 0000000000..79cc3934b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.basic</h1>
+<p class="desc">strokeRect works</p>
+
+
+<script>
+var t = async_test("strokeRect works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.worker.js
new file mode 100644
index 0000000000..de7b13c8f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.basic.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.basic
+// Description:strokeRect works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html
new file mode 100644
index 0000000000..9990f2761e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.clip</h1>
+<p class="desc">strokeRect is affected by clipping regions</p>
+
+
+<script>
+var t = async_test("strokeRect is affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.worker.js
new file mode 100644
index 0000000000..f70a421f1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.clip.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.clip
+// Description:strokeRect is affected by clipping regions
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect is affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html
new file mode 100644
index 0000000000..efc532f33f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.globalalpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.globalalpha</h1>
+<p class="desc">strokeRect is affected by globalAlpha</p>
+
+
+<script>
+var t = async_test("strokeRect is affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.worker.js
new file mode 100644
index 0000000000..2f938b3848
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalalpha.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.globalalpha
+// Description:strokeRect is affected by globalAlpha
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect is affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html
new file mode 100644
index 0000000000..4532604c9a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.globalcomposite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.globalcomposite</h1>
+<p class="desc">strokeRect is not affected by globalCompositeOperation</p>
+
+
+<script>
+var t = async_test("strokeRect is not affected by globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.worker.js
new file mode 100644
index 0000000000..9de70c15a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.globalcomposite.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.globalcomposite
+// Description:strokeRect is not affected by globalCompositeOperation
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect is not affected by globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html
new file mode 100644
index 0000000000..13af38e565
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.negative</h1>
+<p class="desc">strokeRect of negative sizes works</p>
+
+
+<script>
+var t = async_test("strokeRect of negative sizes works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 25;
+ ctx.strokeRect(12, 12, 26, 1);
+ ctx.strokeRect(88, 12, -26, 1);
+ ctx.strokeRect(12, 38, 26, -1);
+ ctx.strokeRect(88, 38, -26, -1);
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.worker.js
new file mode 100644
index 0000000000..bc2aa0434b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.negative.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.negative
+// Description:strokeRect of negative sizes works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect of negative sizes works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 25;
+ ctx.strokeRect(12, 12, 26, 1);
+ ctx.strokeRect(88, 12, -26, 1);
+ ctx.strokeRect(12, 38, 26, -1);
+ ctx.strokeRect(88, 38, -26, -1);
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html
new file mode 100644
index 0000000000..6393797464
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.nonfinite</h1>
+<p class="desc">strokeRect() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("strokeRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 150;
+ ctx.strokeRect(Infinity, 0, 100, 50);
+ ctx.strokeRect(-Infinity, 0, 100, 50);
+ ctx.strokeRect(NaN, 0, 100, 50);
+ ctx.strokeRect(0, Infinity, 100, 50);
+ ctx.strokeRect(0, -Infinity, 100, 50);
+ ctx.strokeRect(0, NaN, 100, 50);
+ ctx.strokeRect(0, 0, Infinity, 50);
+ ctx.strokeRect(0, 0, -Infinity, 50);
+ ctx.strokeRect(0, 0, NaN, 50);
+ ctx.strokeRect(0, 0, 100, Infinity);
+ ctx.strokeRect(0, 0, 100, -Infinity);
+ ctx.strokeRect(0, 0, 100, NaN);
+ ctx.strokeRect(Infinity, Infinity, 100, 50);
+ ctx.strokeRect(Infinity, Infinity, Infinity, 50);
+ ctx.strokeRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.strokeRect(Infinity, Infinity, 100, Infinity);
+ ctx.strokeRect(Infinity, 0, Infinity, 50);
+ ctx.strokeRect(Infinity, 0, Infinity, Infinity);
+ ctx.strokeRect(Infinity, 0, 100, Infinity);
+ ctx.strokeRect(0, Infinity, Infinity, 50);
+ ctx.strokeRect(0, Infinity, Infinity, Infinity);
+ ctx.strokeRect(0, Infinity, 100, Infinity);
+ ctx.strokeRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.worker.js
new file mode 100644
index 0000000000..1878e54c5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.nonfinite.worker.js
@@ -0,0 +1,49 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.nonfinite
+// Description:strokeRect() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 150;
+ ctx.strokeRect(Infinity, 0, 100, 50);
+ ctx.strokeRect(-Infinity, 0, 100, 50);
+ ctx.strokeRect(NaN, 0, 100, 50);
+ ctx.strokeRect(0, Infinity, 100, 50);
+ ctx.strokeRect(0, -Infinity, 100, 50);
+ ctx.strokeRect(0, NaN, 100, 50);
+ ctx.strokeRect(0, 0, Infinity, 50);
+ ctx.strokeRect(0, 0, -Infinity, 50);
+ ctx.strokeRect(0, 0, NaN, 50);
+ ctx.strokeRect(0, 0, 100, Infinity);
+ ctx.strokeRect(0, 0, 100, -Infinity);
+ ctx.strokeRect(0, 0, 100, NaN);
+ ctx.strokeRect(Infinity, Infinity, 100, 50);
+ ctx.strokeRect(Infinity, Infinity, Infinity, 50);
+ ctx.strokeRect(Infinity, Infinity, Infinity, Infinity);
+ ctx.strokeRect(Infinity, Infinity, 100, Infinity);
+ ctx.strokeRect(Infinity, 0, Infinity, 50);
+ ctx.strokeRect(Infinity, 0, Infinity, Infinity);
+ ctx.strokeRect(Infinity, 0, 100, Infinity);
+ ctx.strokeRect(0, Infinity, Infinity, 50);
+ ctx.strokeRect(0, Infinity, Infinity, Infinity);
+ ctx.strokeRect(0, Infinity, 100, Infinity);
+ ctx.strokeRect(0, 0, Infinity, Infinity);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html
new file mode 100644
index 0000000000..da8e903f9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.path</h1>
+<p class="desc">strokeRect does not affect the current path</p>
+
+
+<script>
+var t = async_test("strokeRect does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.worker.js
new file mode 100644
index 0000000000..839b973b17
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.path.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.path
+// Description:strokeRect does not affect the current path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html
new file mode 100644
index 0000000000..2adf24e2b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.shadow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.shadow</h1>
+<p class="desc">strokeRect draws shadows</p>
+
+
+<script>
+var t = async_test("strokeRect draws shadows");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, -75, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.worker.js
new file mode 100644
index 0000000000..36b3455016
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.shadow.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.shadow
+// Description:strokeRect draws shadows
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect draws shadows");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, -75, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html
new file mode 100644
index 0000000000..214ea14023
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.transform</h1>
+<p class="desc">fillRect is affected by transforms</p>
+
+
+<script>
+var t = async_test("fillRect is affected by transforms");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(2.5, -2.6, 5, 0.2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.worker.js
new file mode 100644
index 0000000000..43aab18533
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.transform.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.transform
+// Description:fillRect is affected by transforms
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillRect is affected by transforms");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(2.5, -2.6, 5, 0.2);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html
new file mode 100644
index 0000000000..2c63913fca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.zero.1</h1>
+<p class="desc">strokeRect of 0x0 pixels draws nothing</p>
+
+
+<script>
+var t = async_test("strokeRect of 0x0 pixels draws nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.strokeRect(50, 25, 0, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.worker.js
new file mode 100644
index 0000000000..115017b3bf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.zero.1
+// Description:strokeRect of 0x0 pixels draws nothing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect of 0x0 pixels draws nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.strokeRect(50, 25, 0, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html
new file mode 100644
index 0000000000..16bddea7ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.zero.2</h1>
+<p class="desc">strokeRect of 0x0 pixels draws nothing, including caps and joins</p>
+
+
+<script>
+var t = async_test("strokeRect of 0x0 pixels draws nothing, including caps and joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(50, 25, 0, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.worker.js
new file mode 100644
index 0000000000..973ebec44a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.2.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.zero.2
+// Description:strokeRect of 0x0 pixels draws nothing, including caps and joins
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect of 0x0 pixels draws nothing, including caps and joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(50, 25, 0, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html
new file mode 100644
index 0000000000..8bf3e043db
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.zero.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.zero.3</h1>
+<p class="desc">strokeRect of Nx0 pixels draws a straight line</p>
+
+
+<script>
+var t = async_test("strokeRect of Nx0 pixels draws a straight line");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.worker.js
new file mode 100644
index 0000000000..2612e54fdb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.zero.3
+// Description:strokeRect of Nx0 pixels draws a straight line
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect of Nx0 pixels draws a straight line");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html
new file mode 100644
index 0000000000..87aeaf7c13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.zero.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.zero.4</h1>
+<p class="desc">strokeRect of Nx0 pixels draws a closed line with no caps</p>
+
+
+<script>
+var t = async_test("strokeRect of Nx0 pixels draws a closed line with no caps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.worker.js
new file mode 100644
index 0000000000..3cec206313
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.4.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.zero.4
+// Description:strokeRect of Nx0 pixels draws a closed line with no caps
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect of Nx0 pixels draws a closed line with no caps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html
new file mode 100644
index 0000000000..e03e7aa118
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeRect.zero.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeRect.zero.5</h1>
+<p class="desc">strokeRect of Nx0 pixels draws a closed line with joins</p>
+
+
+<script>
+var t = async_test("strokeRect of Nx0 pixels draws a closed line with joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 250;
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.worker.js
new file mode 100644
index 0000000000..8591409705
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/drawing-rectangles-to-the-canvas/2d.strokeRect.zero.5.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeRect.zero.5
+// Description:strokeRect of Nx0 pixels draws a closed line with joins
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeRect of Nx0 pixels draws a closed line with joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 250;
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html
new file mode 100644
index 0000000000..8e488a5a58
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSHSL.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.CSSHSL</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.CSSHSL</h1>
+<p class="desc">CSSHSL works as color input</p>
+
+
+<script>
+var t = async_test("CSSHSL works as color input");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = new CSSHSL(CSS.deg(180), 0.5, 0.5);
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 64,191,191,255, 3);
+
+ const color = new CSSHSL(CSS.deg(180), 1, 1);
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#ffffff', "ctx.fillStyle", "'#ffffff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+ color.l = 0.5;
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#00ffff', "ctx.fillStyle", "'#00ffff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,255,255);
+
+ ctx.fillStyle = new CSSRGB(1, 0, 1).toHSL();
+ _assertSame(ctx.fillStyle, '#ff00ff', "ctx.fillStyle", "'#ff00ff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,0,255,255);
+
+ color.h = CSS.deg(120);
+ color.s = 1;
+ color.l = 0.5;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html
new file mode 100644
index 0000000000..1670d64295
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.CSSRGB.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.CSSRGB</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.CSSRGB</h1>
+<p class="desc">CSSRGB works as color input</p>
+
+
+<script>
+var t = async_test("CSSRGB works as color input");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = new CSSRGB(1, 0, 1);
+ _assertSame(ctx.fillStyle, '#ff00ff', "ctx.fillStyle", "'#ff00ff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,0,255,255);
+
+ const color = new CSSRGB(0, CSS.percent(50), 0);
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#008000', "ctx.fillStyle", "'#008000'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,128,0,255);
+ color.g = 0;
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, '#000000', "ctx.fillStyle", "'#000000'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+
+ color.alpha = 0;
+ ctx.fillStyle = color;
+ _assertSame(ctx.fillStyle, 'rgba(0, 0, 0, 0)', "ctx.fillStyle", "'rgba(0, 0, 0, 0)'");
+ ctx.reset();
+ color.alpha = 0.5;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,128);
+
+ ctx.fillStyle = new CSSHSL(CSS.deg(0), 1, 1).toRGB();
+ _assertSame(ctx.fillStyle, '#ffffff', "ctx.fillStyle", "'#ffffff'");
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+
+ color.alpha = 1;
+ color.g = 1;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.html
new file mode 100644
index 0000000000..059c551e46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.colormix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.colormix</h1>
+<p class="desc">color-mix works as color input</p>
+
+
+<script>
+var t = async_test("color-mix works as color input");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = "color-mix(in srgb, red, blue)";
+ _assertSame(ctx.fillStyle, 'color(srgb 0.5 0 0.5)', "ctx.fillStyle", "'color(srgb 0.5 0 0.5)'");
+ ctx.fillStyle = "color-mix(in srgb, red, color(srgb 1 0 0))";
+ _assertSame(ctx.fillStyle, 'color(srgb 1 0 0)', "ctx.fillStyle", "'color(srgb 1 0 0)'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.worker.js
new file mode 100644
index 0000000000..d015790ead
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.colormix.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.colormix
+// Description:color-mix works as color input
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("color-mix works as color input");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = "color-mix(in srgb, red, blue)";
+ _assertSame(ctx.fillStyle, 'color(srgb 0.5 0 0.5)', "ctx.fillStyle", "'color(srgb 0.5 0 0.5)'");
+ ctx.fillStyle = "color-mix(in srgb, red, color(srgb 1 0 0))";
+ _assertSame(ctx.fillStyle, 'color(srgb 1 0 0)', "ctx.fillStyle", "'color(srgb 1 0 0)'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.html
new file mode 100644
index 0000000000..58075168e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.default</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.fillStyle, '#000000', "ctx.fillStyle", "'#000000'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.worker.js
new file mode 100644
index 0000000000..34a6f1276a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.default.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.default
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.fillStyle, '#000000', "ctx.fillStyle", "'#000000'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html
new file mode 100644
index 0000000000..cd0b0c2437
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.get.halftransparent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.get.halftransparent</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(255,255,255,0.5)';
+ _assertSame(ctx.fillStyle, 'rgba(255, 255, 255, 0.5)', "ctx.fillStyle", "'rgba(255, 255, 255, 0.5)'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.worker.js
new file mode 100644
index 0000000000..7590816b32
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.halftransparent.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.get.halftransparent
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(255,255,255,0.5)';
+ _assertSame(ctx.fillStyle, 'rgba(255, 255, 255, 0.5)', "ctx.fillStyle", "'rgba(255, 255, 255, 0.5)'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html
new file mode 100644
index 0000000000..6be295ae0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.get.semitransparent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.get.semitransparent</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(255,255,255,0.45)';
+ assert_regexp_match(ctx.fillStyle, /^rgba\(255, 255, 255, 0\.4\d+\)$/);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.worker.js
new file mode 100644
index 0000000000..1c25bc2ed5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.semitransparent.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.get.semitransparent
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(255,255,255,0.45)';
+ assert_regexp_match(ctx.fillStyle, /^rgba\(255, 255, 255, 0\.4\d+\)$/);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.html
new file mode 100644
index 0000000000..4d8ccc0ff4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.get.solid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.get.solid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fa0';
+ _assertSame(ctx.fillStyle, '#ffaa00', "ctx.fillStyle", "'#ffaa00'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.worker.js
new file mode 100644
index 0000000000..efec71ca9e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.solid.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.get.solid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fa0';
+ _assertSame(ctx.fillStyle, '#ffaa00', "ctx.fillStyle", "'#ffaa00'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.html
new file mode 100644
index 0000000000..8fe102f2b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.get.transparent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.get.transparent</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0,0,0,0)';
+ _assertSame(ctx.fillStyle, 'rgba(0, 0, 0, 0)', "ctx.fillStyle", "'rgba(0, 0, 0, 0)'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.worker.js
new file mode 100644
index 0000000000..51542bad82
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.get.transparent.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.get.transparent
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0,0,0,0)';
+ _assertSame(ctx.fillStyle, 'rgba(0, 0, 0, 0)', "ctx.fillStyle", "'rgba(0, 0, 0, 0)'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.html
new file mode 100644
index 0000000000..a30bc4ac7c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.invalidstring</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.invalidstring</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = 'invalid';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.worker.js
new file mode 100644
index 0000000000..f2f5ccacce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidstring.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.invalidstring
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = 'invalid';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.html
new file mode 100644
index 0000000000..23814ae87c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.invalidtype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.invalidtype</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = null;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.worker.js
new file mode 100644
index 0000000000..13e10e1254
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.invalidtype.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.invalidtype
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = null;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html
new file mode 100644
index 0000000000..222d7f6077
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.worker.js
new file mode 100644
index 0000000000..74137880b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html
new file mode 100644
index 0000000000..b2c93c1e26
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0% / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.worker.js
new file mode 100644
index 0000000000..3ccd75a400
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0% / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html
new file mode 100644
index 0000000000..fc8726904c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.worker.js
new file mode 100644
index 0000000000..bfaba36446
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html
new file mode 100644
index 0000000000..71cb327c5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.worker.js
new file mode 100644
index 0000000000..afe12657bc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html
new file mode 100644
index 0000000000..787d5e7644
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.worker.js
new file mode 100644
index 0000000000..05c77b0a1d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-5
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html
new file mode 100644
index 0000000000..8acc67f968
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.worker.js
new file mode 100644
index 0000000000..8ff08394b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-6
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html
new file mode 100644
index 0000000000..dc295d070a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-7</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-7</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(133.33333333grad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.worker.js
new file mode 100644
index 0000000000..9d0513ffca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-7.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-7
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(133.33333333grad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html
new file mode 100644
index 0000000000..50970585ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-8</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(2.0943951024rad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.worker.js
new file mode 100644
index 0000000000..ce56342cea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-8.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-8
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(2.0943951024rad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html
new file mode 100644
index 0000000000..47cd157c44
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsl-9</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsl-9</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(0.3333333333turn, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.worker.js
new file mode 100644
index 0000000000..e45f55930d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsl-9.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsl-9
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(0.3333333333turn, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html
new file mode 100644
index 0000000000..2d1e46f1a9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.worker.js
new file mode 100644
index 0000000000..2a1157ed1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html
new file mode 100644
index 0000000000..f5531f68e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0% / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.worker.js
new file mode 100644
index 0000000000..23cd58d1a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120 100.0% 50.0% / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html
new file mode 100644
index 0000000000..fde2328c43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.worker.js
new file mode 100644
index 0000000000..64577bc348
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html
new file mode 100644
index 0000000000..3b6e1f1347
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.worker.js
new file mode 100644
index 0000000000..05b08f0a0c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html
new file mode 100644
index 0000000000..b0677c16dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.worker.js
new file mode 100644
index 0000000000..51484f3aef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-5
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html
new file mode 100644
index 0000000000..809d11c4cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.worker.js
new file mode 100644
index 0000000000..7b224e5c93
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-6
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120deg, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html
new file mode 100644
index 0000000000..48c3c6927e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-7</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-7</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(133.33333333grad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.worker.js
new file mode 100644
index 0000000000..ed51a5df40
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-7.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-7
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(133.33333333grad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html
new file mode 100644
index 0000000000..f49b313a1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-8</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(2.0943951024rad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.worker.js
new file mode 100644
index 0000000000..c61fb1a1fc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-8.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-8
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(2.0943951024rad, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html
new file mode 100644
index 0000000000..68c4e224a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-hsla-9</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-hsla-9</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(0.3333333333turn, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.worker.js
new file mode 100644
index 0000000000..51541b7148
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-hsla-9.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-hsla-9
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(0.3333333333turn, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html
new file mode 100644
index 0000000000..c9d75ca5c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgb-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255.0, 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.worker.js
new file mode 100644
index 0000000000..f0a67250f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgb-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255.0, 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html
new file mode 100644
index 0000000000..0acc23ef95
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgb-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.worker.js
new file mode 100644
index 0000000000..eb6b952b4c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgb-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html
new file mode 100644
index 0000000000..85c2606c98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgb-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.worker.js
new file mode 100644
index 0000000000..9db5b7c33e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgb-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html
new file mode 100644
index 0000000000..e028260ee5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgb-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.worker.js
new file mode 100644
index 0000000000..fecb3ecb6e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgb-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html
new file mode 100644
index 0000000000..51ace916b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgb-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0 / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.worker.js
new file mode 100644
index 0000000000..03948b0c69
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgb-5
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0 / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html
new file mode 100644
index 0000000000..6df2f914e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgb-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgb-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0 / 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.worker.js
new file mode 100644
index 0000000000..5f31d9a9f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgb-6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgb-6
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0 255 0 / 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html
new file mode 100644
index 0000000000..19d726ee3b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgba-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255.0, 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.worker.js
new file mode 100644
index 0000000000..24f278221e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgba-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255.0, 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html
new file mode 100644
index 0000000000..1603ae93ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgba-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.worker.js
new file mode 100644
index 0000000000..fcda86bae2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgba-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html
new file mode 100644
index 0000000000..53ad71781a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgba-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.worker.js
new file mode 100644
index 0000000000..164f17f3d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgba-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html
new file mode 100644
index 0000000000..3dc9f9c7a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgba-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.worker.js
new file mode 100644
index 0000000000..da512a261e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgba-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html
new file mode 100644
index 0000000000..db0e891f22
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgba-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0 / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.worker.js
new file mode 100644
index 0000000000..7f10cba4d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgba-5
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0 / 0.2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html
new file mode 100644
index 0000000000..c4ec4622a5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.css-color-4-rgba-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.css-color-4-rgba-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0 / 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.worker.js
new file mode 100644
index 0000000000..2d81992eba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.css-color-4-rgba-6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.css-color-4-rgba-6
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0 255 0 / 20%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,51);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html
new file mode 100644
index 0000000000..90c4d4f5d7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hex3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hex3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.worker.js
new file mode 100644
index 0000000000..7ee281b443
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hex3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html
new file mode 100644
index 0000000000..8a6260fa89
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hex4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hex4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#0f0f';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.worker.js
new file mode 100644
index 0000000000..53001f9580
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hex4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#0f0f';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html
new file mode 100644
index 0000000000..02f698ea30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hex6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hex6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#00fF00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.worker.js
new file mode 100644
index 0000000000..e9420b62e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hex6
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#00fF00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html
new file mode 100644
index 0000000000..1563bab113
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hex8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hex8</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#00ff00ff';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.worker.js
new file mode 100644
index 0000000000..35cdc5c292
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hex8.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hex8
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '#00ff00ff';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html
new file mode 100644
index 0000000000..96e6515a61
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.worker.js
new file mode 100644
index 0000000000..204df1a35f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html
new file mode 100644
index 0000000000..b6f8f2bb76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl( -240 , 100% , 50% )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.worker.js
new file mode 100644
index 0000000000..f282d3ca1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl( -240 , 100% , 50% )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html
new file mode 100644
index 0000000000..5ed3b96b9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(360120, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.worker.js
new file mode 100644
index 0000000000..a4abd304a8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(360120, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html
new file mode 100644
index 0000000000..f91edd75bf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(-360240, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.worker.js
new file mode 100644
index 0000000000..19cbfd08cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(-360240, 100%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html
new file mode 100644
index 0000000000..c4624da0c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.worker.js
new file mode 100644
index 0000000000..49689b8274
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-5
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120.0, 100.0%, 50.0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html
new file mode 100644
index 0000000000..5baa5b3b00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(+120, +100%, +50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.worker.js
new file mode 100644
index 0000000000..9f99d96403
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-6
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(+120, +100%, +50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html
new file mode 100644
index 0000000000..db43c45dc8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 200%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.worker.js
new file mode 100644
index 0000000000..868beda764
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-clamp-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 200%, 50%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html
new file mode 100644
index 0000000000..a5b399a748
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, -200%, 49.9%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 127,127,127,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.worker.js
new file mode 100644
index 0000000000..2f1d2d72e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-clamp-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, -200%, 49.9%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 127,127,127,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html
new file mode 100644
index 0000000000..cfa6d82382
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-clamp-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-clamp-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, 200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.worker.js
new file mode 100644
index 0000000000..4c71d6d140
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-clamp-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, 200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html
new file mode 100644
index 0000000000..a3bfd8c22f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsl-clamp-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsl-clamp-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, -200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.worker.js
new file mode 100644
index 0000000000..e4477f5cb8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsl-clamp-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsl-clamp-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsl(120, 100%, -200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html
new file mode 100644
index 0000000000..67a65da730
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 50%, 0.499)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.worker.js
new file mode 100644
index 0000000000..c002368227
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 50%, 0.499)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html
new file mode 100644
index 0000000000..c63fac5dd6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla( 120.0 , 100.0% , 50.0% , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.worker.js
new file mode 100644
index 0000000000..aca5d8d916
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla( 120.0 , 100.0% , 50.0% , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html
new file mode 100644
index 0000000000..ebd766165d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 200%, 50%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.worker.js
new file mode 100644
index 0000000000..6a29123d95
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-clamp-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 200%, 50%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html
new file mode 100644
index 0000000000..91ec54841c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, -200%, 49.9%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 127,127,127,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.worker.js
new file mode 100644
index 0000000000..c27c9f8619
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-clamp-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, -200%, 49.9%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 127,127,127,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html
new file mode 100644
index 0000000000..343bf8b2e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-clamp-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-clamp-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 200%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.worker.js
new file mode 100644
index 0000000000..64f459c23f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-clamp-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 200%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 255,255,255,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html
new file mode 100644
index 0000000000..c54d409934
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-clamp-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-clamp-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, -200%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.worker.js
new file mode 100644
index 0000000000..b24163a786
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-clamp-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, -200%, 1)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html
new file mode 100644
index 0000000000..d068ffa921
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-clamp-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-clamp-5</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 50%, 2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.worker.js
new file mode 100644
index 0000000000..a10af90a0f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-clamp-5
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 50%, 2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html
new file mode 100644
index 0000000000..f8f0a78f21
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.hsla-clamp-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.hsla-clamp-6</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 0%, -2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.worker.js
new file mode 100644
index 0000000000..da6cd93e2a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.hsla-clamp-6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.hsla-clamp-6
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'hsla(120, 100%, 0%, -2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.html
new file mode 100644
index 0000000000..fc1c1af18b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.html4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.html4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'limE';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.worker.js
new file mode 100644
index 0000000000..7430608f63
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.html4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.html4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'limE';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html
new file mode 100644
index 0000000000..3edffc6d93
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50% / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.worker.js
new file mode 100644
index 0000000000..054568e1de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsl-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50% / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html
new file mode 100644
index 0000000000..477b318f41
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0 100% 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.worker.js
new file mode 100644
index 0000000000..74d6904f84
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsl-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0 100% 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html
new file mode 100644
index 0000000000..e2092666c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100% 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.worker.js
new file mode 100644
index 0000000000..7e930df400
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsl-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100% 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html
new file mode 100644
index 0000000000..5bcc1755b0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0 100% 50% /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.worker.js
new file mode 100644
index 0000000000..cca9d52ab1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsl-4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0 100% 50% /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html
new file mode 100644
index 0000000000..ba46540802
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsl-5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50% /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.worker.js
new file mode 100644
index 0000000000..5c17b9eeb3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsl-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsl-5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50% /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html
new file mode 100644
index 0000000000..a5f8f3fe9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsla-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 100%, 50% / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.worker.js
new file mode 100644
index 0000000000..1ab7e713d0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsla-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 100%, 50% / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html
new file mode 100644
index 0000000000..bd543220d0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsla-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0 100% 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.worker.js
new file mode 100644
index 0000000000..9f1aeed563
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsla-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0 100% 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html
new file mode 100644
index 0000000000..e33b9415b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-hsla-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-hsla-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 100% 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.worker.js
new file mode 100644
index 0000000000..c06a31941b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-hsla-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-hsla-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 100% 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html
new file mode 100644
index 0000000000..8fbbc7ae51
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, 0, 0 / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.worker.js
new file mode 100644
index 0000000000..a728e8d358
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgb-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, 0, 0 / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html
new file mode 100644
index 0000000000..adc8297488
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255 0 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.worker.js
new file mode 100644
index 0000000000..da9b95c191
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgb-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255 0 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html
new file mode 100644
index 0000000000..4d385d56cc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.worker.js
new file mode 100644
index 0000000000..eee7fb92fd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgb-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html
new file mode 100644
index 0000000000..6b855b4357
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(0 0 0 /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.worker.js
new file mode 100644
index 0000000000..2b25416de7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgb-4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(0 0 0 /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html
new file mode 100644
index 0000000000..13fadb9a24
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgb-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgb-5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(0, 0, 0 /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.worker.js
new file mode 100644
index 0000000000..7932932d93
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgb-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgb-5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(0, 0, 0 /)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html
new file mode 100644
index 0000000000..5353f77b8f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgba-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgba-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0 / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.worker.js
new file mode 100644
index 0000000000..ef559c45f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgba-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0 / 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html
new file mode 100644
index 0000000000..aaa555aa05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgba-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgba-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255 0 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.worker.js
new file mode 100644
index 0000000000..7a06f832e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgba-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255 0 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html
new file mode 100644
index 0000000000..e8c0588851
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.css-color-4-rgba-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.css-color-4-rgba-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.worker.js
new file mode 100644
index 0000000000..65ed246a39
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.css-color-4-rgba-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.css-color-4-rgba-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html
new file mode 100644
index 0000000000..28a7ff4739
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#f'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.worker.js
new file mode 100644
index 0000000000..0cb79048c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#f'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html
new file mode 100644
index 0000000000..0dcf0f8282
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#f0'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.worker.js
new file mode 100644
index 0000000000..d2dd193748
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#f0'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html
new file mode 100644
index 0000000000..8e1bd9fa0f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#g00'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.worker.js
new file mode 100644
index 0000000000..805becb3b8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#g00'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html
new file mode 100644
index 0000000000..f59991d317
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg00'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.worker.js
new file mode 100644
index 0000000000..1499fb7e13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg00'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html
new file mode 100644
index 0000000000..9567114a13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#ff000'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.worker.js
new file mode 100644
index 0000000000..d50daeb4c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#ff000'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html
new file mode 100644
index 0000000000..b36d0c8654
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex6</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg0000'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.worker.js
new file mode 100644
index 0000000000..606aa4f458
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex6
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg0000'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html
new file mode 100644
index 0000000000..5b38e7873f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex7</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex7</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#ff0000f'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.worker.js
new file mode 100644
index 0000000000..92ff04a530
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex7.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex7
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#ff0000f'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html
new file mode 100644
index 0000000000..1eda0c74a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hex8</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hex8</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg0000ff'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.worker.js
new file mode 100644
index 0000000000..4508cc567c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hex8.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hex8
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '#fg0000ff'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html
new file mode 100644
index 0000000000..9ff3c68fe2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsl-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsl-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0%, 100%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.worker.js
new file mode 100644
index 0000000000..e3cbe474b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsl-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0%, 100%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html
new file mode 100644
index 0000000000..46fac5fd40
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsl-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsl-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(z, 100%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.worker.js
new file mode 100644
index 0000000000..56c36f3688
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsl-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(z, 100%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html
new file mode 100644
index 0000000000..1f05e8d944
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsl-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsl-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 0, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.worker.js
new file mode 100644
index 0000000000..491b5bdf49
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsl-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 0, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html
new file mode 100644
index 0000000000..dd2cec7977
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsl-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsl-4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.worker.js
new file mode 100644
index 0000000000..fef0f0aee2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsl-4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html
new file mode 100644
index 0000000000..909e230b16
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsl-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsl-5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100.%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.worker.js
new file mode 100644
index 0000000000..635e0bf72e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsl-5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100.%, 50%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html
new file mode 100644
index 0000000000..9bb652c076
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsl-6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsl-6</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50%,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.worker.js
new file mode 100644
index 0000000000..efe1aa7ded
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsl-6.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsl-6
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsl(0, 100%, 50%,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html
new file mode 100644
index 0000000000..9b553c669d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsla-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsla-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0%, 100%, 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.worker.js
new file mode 100644
index 0000000000..757ca911fb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsla-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0%, 100%, 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html
new file mode 100644
index 0000000000..d894bc42fd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsla-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsla-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 0, 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.worker.js
new file mode 100644
index 0000000000..be2b2ddf00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsla-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 0, 50%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html
new file mode 100644
index 0000000000..8901a112b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.hsla-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.hsla-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 0, 50%, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.worker.js
new file mode 100644
index 0000000000..52d3707f70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.hsla-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.hsla-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'hsla(0, 0, 50%, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html
new file mode 100644
index 0000000000..ceb6c53a83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.name-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.name-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'darkbrown'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.worker.js
new file mode 100644
index 0000000000..6331a2dfb2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.name-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'darkbrown'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html
new file mode 100644
index 0000000000..684a665574
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.name-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.name-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'firebrick1'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.worker.js
new file mode 100644
index 0000000000..101646c995
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.name-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'firebrick1'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html
new file mode 100644
index 0000000000..ebf508f464
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.name-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.name-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'red blue'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.worker.js
new file mode 100644
index 0000000000..61e43e03d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.name-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'red blue'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html
new file mode 100644
index 0000000000..ba1f71b123
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.name-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.name-4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '"red"'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.worker.js
new file mode 100644
index 0000000000..b1efecdc57
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.name-4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '"red"'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html
new file mode 100644
index 0000000000..a889a387af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.name-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.name-5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '"red'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.worker.js
new file mode 100644
index 0000000000..e519fff426
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.name-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.name-5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '"red'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html
new file mode 100644
index 0000000000..e1fb32a179
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgb-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgb-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255.0, 0, 0,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.worker.js
new file mode 100644
index 0000000000..8255f35478
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgb-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255.0, 0, 0,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html
new file mode 100644
index 0000000000..54d7daf999
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgb-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgb-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(100%, 0, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.worker.js
new file mode 100644
index 0000000000..c0787e32cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgb-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(100%, 0, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html
new file mode 100644
index 0000000000..9874fc6f74
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgb-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgb-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, - 1, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.worker.js
new file mode 100644
index 0000000000..62365ac17a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgb-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgb-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgb(255, - 1, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html
new file mode 100644
index 0000000000..fbfa4baef2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgba-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgba-1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(100%, 0, 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.worker.js
new file mode 100644
index 0000000000..53063fd9b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgba-1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(100%, 0, 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html
new file mode 100644
index 0000000000..43cd1763c1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgba-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgba-2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1. 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.worker.js
new file mode 100644
index 0000000000..df7079284c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgba-2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1. 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html
new file mode 100644
index 0000000000..96955226a5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgba-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgba-3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1.)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.worker.js
new file mode 100644
index 0000000000..8f45ef582f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgba-3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1.)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html
new file mode 100644
index 0000000000..9334d693ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgba-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgba-4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, '; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.worker.js
new file mode 100644
index 0000000000..47549bea5e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgba-4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, '; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html
new file mode 100644
index 0000000000..7b53652a94
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.invalid.rgba-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.invalid.rgba-5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.worker.js
new file mode 100644
index 0000000000..562b9661ec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.invalid.rgba-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.invalid.rgba-5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = 'rgba(255, 0, 0, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html
new file mode 100644
index 0000000000..c9e9e4c413
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-1000, 1000, -1000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.worker.js
new file mode 100644
index 0000000000..51b81c5bba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-clamp-1
+// Description:
+// Note:<p class="notes">Assumes colors are clamped to [0,255].
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-1000, 1000, -1000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html
new file mode 100644
index 0000000000..98df8d67e4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-200%, 200%, -200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.worker.js
new file mode 100644
index 0000000000..bfe9102f99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-clamp-2
+// Description:
+// Note:<p class="notes">Assumes colors are clamped to [0,255].
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-200%, 200%, -200%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html
new file mode 100644
index 0000000000..70f5ed05f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-clamp-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-clamp-3</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-2147483649, 4294967298, -18446744073709551619)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.worker.js
new file mode 100644
index 0000000000..809d209348
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-clamp-3
+// Description:
+// Note:<p class="notes">Assumes colors are clamped to [0,255].
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-2147483649, 4294967298, -18446744073709551619)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html
new file mode 100644
index 0000000000..1f387998e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-clamp-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-clamp-4</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-1000000000000000000000000000000000000000, 1000000000000000000000000000000000000000, -1000000000000000000000000000000000000000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.worker.js
new file mode 100644
index 0000000000..c0ec5ec921
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-clamp-4
+// Description:
+// Note:<p class="notes">Assumes colors are clamped to [0,255].
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-1000000000000000000000000000000000000000, 1000000000000000000000000000000000000000, -1000000000000000000000000000000000000000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html
new file mode 100644
index 0000000000..c2ac0b94d2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-clamp-5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-clamp-5</h1>
+<p class="desc"></p>
+
+<p class="notes">Assumes colors are clamped to [0,255].
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.worker.js
new file mode 100644
index 0000000000..ac2692ec4b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-clamp-5.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-clamp-5
+// Description:
+// Note:<p class="notes">Assumes colors are clamped to [0,255].
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html
new file mode 100644
index 0000000000..2979d7da98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-eof</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-eof</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.worker.js
new file mode 100644
index 0000000000..997df7b03f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-eof.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-eof
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0, 255, 0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html
new file mode 100644
index 0000000000..67ba77f3e3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-num</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-num</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0,255,0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.worker.js
new file mode 100644
index 0000000000..1d54b1f189
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-num.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-num
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0,255,0)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html
new file mode 100644
index 0000000000..8fe3be55ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgb-percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgb-percent</h1>
+<p class="desc"></p>
+
+<p class="notes">CSS3 Color says "The integer value 255 corresponds to 100%". (In particular, it is not 254...)
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0% ,100% ,0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.worker.js
new file mode 100644
index 0000000000..824376083e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgb-percent.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgb-percent
+// Description:
+// Note:<p class="notes">CSS3 Color says "The integer value 255 corresponds to 100%". (In particular, it is not 254...)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgb(0% ,100% ,0%)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html
new file mode 100644
index 0000000000..af3acb95e9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-clamp-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-clamp-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, -2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.worker.js
new file mode 100644
index 0000000000..e3a5bf56ea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-clamp-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, -2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html
new file mode 100644
index 0000000000..32ee979894
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-clamp-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-clamp-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.worker.js
new file mode 100644
index 0000000000..612c40b675
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-clamp-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-clamp-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 2)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html
new file mode 100644
index 0000000000..baa42cde18
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-eof</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-eof</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 1';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.worker.js
new file mode 100644
index 0000000000..73e0b4fd43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-eof.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-eof
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0, 255, 0, 1';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html
new file mode 100644
index 0000000000..eaa83e1801
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-num-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-num-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , .499 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.worker.js
new file mode 100644
index 0000000000..bb1a97fbe7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-num-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , .499 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html
new file mode 100644
index 0000000000..47bf3ddced
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-num-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-num-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 0.499 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.worker.js
new file mode 100644
index 0000000000..5629ca5cb2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-num-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-num-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 0.499 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html
new file mode 100644
index 0000000000..068befd9b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-percent</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0%,100%,0%,0.499)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.worker.js
new file mode 100644
index 0000000000..6d90415325
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-percent.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-percent
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba(0%,100%,0%,0.499)';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,127);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html
new file mode 100644
index 0000000000..0e58836e5d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-solid-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-solid-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.worker.js
new file mode 100644
index 0000000000..cddedb7d59
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-solid-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html
new file mode 100644
index 0000000000..8da29eeffb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-solid-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-solid-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 1.0 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.worker.js
new file mode 100644
index 0000000000..126cbb9269
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-solid-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , 1.0 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html
new file mode 100644
index 0000000000..e67374c541
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-solid-3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-solid-3</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , +1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.worker.js
new file mode 100644
index 0000000000..d8d1513c90
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-3.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-solid-3
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( 0 , 255 , 0 , +1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html
new file mode 100644
index 0000000000..777aacea70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.rgba-solid-4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.rgba-solid-4</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( -0 , 255 , +0 , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.worker.js
new file mode 100644
index 0000000000..aa516a2d7f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.rgba-solid-4.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.rgba-solid-4
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'rgba( -0 , 255 , +0 , 1 )';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html
new file mode 100644
index 0000000000..8dc6844ae9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.svg-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.svg-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'gray';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 128,128,128,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.worker.js
new file mode 100644
index 0000000000..e8660caf6d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.svg-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'gray';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 128,128,128,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html
new file mode 100644
index 0000000000..2833565006
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.svg-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.svg-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 128,128,128,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.worker.js
new file mode 100644
index 0000000000..3488200d86
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.svg-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.svg-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 128,128,128,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.html
new file mode 100644
index 0000000000..6e124062b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.system</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.system</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'ThreeDDarkShadow';
+ assert_regexp_match(ctx.fillStyle, /^#(?!(FF0000|ff0000|f00)$)/); // test that it's not red
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.worker.js
new file mode 100644
index 0000000000..cf62855af9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.system.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.system
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'ThreeDDarkShadow';
+ assert_regexp_match(ctx.fillStyle, /^#(?!(FF0000|ff0000|f00)$)/); // test that it's not red
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html
new file mode 100644
index 0000000000..a595d70bc0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.transparent-1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.transparent-1</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'transparent';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.worker.js
new file mode 100644
index 0000000000..7f9a975bc1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.transparent-1
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'transparent';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html
new file mode 100644
index 0000000000..0f2a7e0609
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.parse.transparent-2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.parse.transparent-2</h1>
+<p class="desc"></p>
+
+<p class="notes">
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'TrAnSpArEnT';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.worker.js
new file mode 100644
index 0000000000..794ca926dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.parse.transparent-2.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.parse.transparent-2
+// Description:
+// Note:<p class="notes">
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'TrAnSpArEnT';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html
new file mode 100644
index 0000000000..3e56bd2b62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.fillStyle.toStringFunctionCallback</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.fillStyle.toStringFunctionCallback</h1>
+<p class="desc">Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified</p>
+
+
+<script>
+var t = async_test("Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = { toString: function() { return "#008000"; } };
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ ctx.fillStyle = {};
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ ctx.fillStyle = 800000;
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ assert_throws_js(TypeError, function() { ctx.fillStyle = { toString: function() { throw new TypeError; } }; });
+ ctx.strokeStyle = { toString: function() { return "#008000"; } };
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ ctx.strokeStyle = {};
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ ctx.strokeStyle = 800000;
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ assert_throws_js(TypeError, function() { ctx.strokeStyle = { toString: function() { throw new TypeError; } }; });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.worker.js
new file mode 100644
index 0000000000..3ae93092b8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.fillStyle.toStringFunctionCallback.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.fillStyle.toStringFunctionCallback
+// Description:Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = { toString: function() { return "#008000"; } };
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ ctx.fillStyle = {};
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ ctx.fillStyle = 800000;
+ _assertSame(ctx.fillStyle, "#008000", "ctx.fillStyle", "\"#008000\"");
+ assert_throws_js(TypeError, function() { ctx.fillStyle = { toString: function() { throw new TypeError; } }; });
+ ctx.strokeStyle = { toString: function() { return "#008000"; } };
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ ctx.strokeStyle = {};
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ ctx.strokeStyle = 800000;
+ _assertSame(ctx.strokeStyle, "#008000", "ctx.strokeStyle", "\"#008000\"");
+ assert_throws_js(TypeError, function() { ctx.strokeStyle = { toString: function() { throw new TypeError; } }; });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html
new file mode 100644
index 0000000000..5ccb19e09c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.conic.invalid.inputs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.conic.invalid.inputs</h1>
+<p class="desc">Conic gradient function with invalid inputs</p>
+
+
+<script>
+var t = async_test("Conic gradient function with invalid inputs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(-Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(NaN, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, -Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, NaN, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, Infinity, Infinity); });
+
+ const g = ctx.createConicGradient(0, 0, 25);
+ assert_throws_js(TypeError, function() { g.addColorStop(-Infinity, '#f00'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(NaN, '#f00'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, -Infinity); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, NaN); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.worker.js
new file mode 100644
index 0000000000..19b603ea75
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.invalid.inputs.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.conic.invalid.inputs
+// Description:Conic gradient function with invalid inputs
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Conic gradient function with invalid inputs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(-Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(NaN, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, -Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, NaN, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, 0, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createConicGradient(0, Infinity, Infinity); });
+
+ const g = ctx.createConicGradient(0, 0, 25);
+ assert_throws_js(TypeError, function() { g.addColorStop(-Infinity, '#f00'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(NaN, '#f00'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, -Infinity); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, NaN); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html
new file mode 100644
index 0000000000..848f1496ea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.conic.negative.rotation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.conic.negative.rotation</h1>
+<p class="desc">Conic gradient with negative rotation</p>
+
+
+<script>
+var t = async_test("Conic gradient with negative rotation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const g = ctx.createConicGradient(-Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,15, 255,0,0,255, 3);
+ _assertPixelApprox(canvas, 75,40, 0,255,0,255, 3);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.worker.js
new file mode 100644
index 0000000000..1f9735ee08
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.negative.rotation.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.conic.negative.rotation
+// Description:Conic gradient with negative rotation
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Conic gradient with negative rotation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const g = ctx.createConicGradient(-Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,15, 255,0,0,255, 3);
+ _assertPixelApprox(canvas, 75,40, 0,255,0,255, 3);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html
new file mode 100644
index 0000000000..06b593904f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.conic.positive.rotation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.conic.positive.rotation</h1>
+<p class="desc">Conic gradient with positive rotation</p>
+
+
+<script>
+var t = async_test("Conic gradient with positive rotation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const g = ctx.createConicGradient(3*Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,15, 255,0,0,255, 3);
+ _assertPixelApprox(canvas, 75,40, 0,255,0,255, 3);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.worker.js
new file mode 100644
index 0000000000..45bbf40313
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.conic.positive.rotation.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.conic.positive.rotation
+// Description:Conic gradient with positive rotation
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Conic gradient with positive rotation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const g = ctx.createConicGradient(3*Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,15, 255,0,0,255, 3);
+ _assertPixelApprox(canvas, 75,40, 0,255,0,255, 3);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.html
new file mode 100644
index 0000000000..bad1ff4767
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.empty</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.worker.js
new file mode 100644
index 0000000000..225de25823
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.empty.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.empty
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html
new file mode 100644
index 0000000000..525cb79e03
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.alpha</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(0,0,255, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 191,191,63,255, 3);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 3);
+ _assertPixelApprox(canvas, 75,25, 63,63,191,255, 3);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.png b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.png
new file mode 100644
index 0000000000..af5ac0f07d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.worker.js
new file mode 100644
index 0000000000..5c2f7e07b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.alpha
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(0,0,255, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 191,191,63,255, 3);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 3);
+ _assertPixelApprox(canvas, 75,25, 63,63,191,255, 3);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.html
new file mode 100644
index 0000000000..c742eff2f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.color</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.color</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 191,191,63,255, 3);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 3);
+ _assertPixelApprox(canvas, 75,25, 63,63,191,255, 3);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.png b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.png
new file mode 100644
index 0000000000..af5ac0f07d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.worker.js
new file mode 100644
index 0000000000..6d273b7b43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.color.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.color
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 191,191,63,255, 3);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 3);
+ _assertPixelApprox(canvas, 75,25, 63,63,191,255, 3);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html
new file mode 100644
index 0000000000..00575c399a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.coloralpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.coloralpha</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(255,255,0, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 190,190,65,65, 3);
+ _assertPixelApprox(canvas, 50,25, 126,126,128,128, 3);
+ _assertPixelApprox(canvas, 75,25, 62,62,192,192, 3);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.png b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.png
new file mode 100644
index 0000000000..552e6ee44b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.worker.js
new file mode 100644
index 0000000000..1462cb59e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.coloralpha
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(255,255,0, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 25,25, 190,190,65,65, 3);
+ _assertPixelApprox(canvas, 50,25, 126,126,128,128, 3);
+ _assertPixelApprox(canvas, 75,25, 62,62,192,192, 3);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html
new file mode 100644
index 0000000000..3f2594f2cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.multiple</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.5, '#0ff');
+ g.addColorStop(1, '#f0f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ _assertPixelApprox(canvas, 50,25, 127,255,127,255, 3);
+ _assertPixelApprox(canvas, 100,25, 0,255,255,255, 3);
+ _assertPixelApprox(canvas, 150,25, 127,127,255,255, 3);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.png b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.png
new file mode 100644
index 0000000000..86122450d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js
new file mode 100644
index 0000000000..ebfcddca9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.multiple.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.multiple
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.5, '#0ff');
+ g.addColorStop(1, '#f0f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ _assertPixelApprox(canvas, 50,25, 127,255,127,255, 3);
+ _assertPixelApprox(canvas, 100,25, 0,255,255,255, 3);
+ _assertPixelApprox(canvas, 150,25, 127,127,255,255, 3);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.html
new file mode 100644
index 0000000000..02ca008518
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.outside</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(25, 0, 75, 0);
+ g.addColorStop(0.4, '#0f0');
+ g.addColorStop(0.6, '#0f0');
+
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 20,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.worker.js
new file mode 100644
index 0000000000..d6c8961661
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.outside.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.outside
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(25, 0, 75, 0);
+ g.addColorStop(0.4, '#0f0');
+ g.addColorStop(0.6, '#0f0');
+
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 20,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 80,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html
new file mode 100644
index 0000000000..0139da177a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.overlap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.overlap</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.25, '#00f');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#ff0');
+ g.addColorStop(0.5, '#00f');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.75, '#00f');
+ g.addColorStop(0.75, '#f00');
+ g.addColorStop(0.75, '#ff0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ _assertPixelApprox(canvas, 49,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 51,25, 255,255,0,255, 16);
+ _assertPixelApprox(canvas, 99,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 101,25, 255,255,0,255, 16);
+ _assertPixelApprox(canvas, 149,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 151,25, 255,255,0,255, 16);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.png b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.png
new file mode 100644
index 0000000000..5c2bb964e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js
new file mode 100644
index 0000000000..d404deab26
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap.worker.js
@@ -0,0 +1,47 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.overlap
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.25, '#00f');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#ff0');
+ g.addColorStop(0.5, '#00f');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.75, '#00f');
+ g.addColorStop(0.75, '#f00');
+ g.addColorStop(0.75, '#ff0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ _assertPixelApprox(canvas, 49,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 51,25, 255,255,0,255, 16);
+ _assertPixelApprox(canvas, 99,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 101,25, 255,255,0,255, 16);
+ _assertPixelApprox(canvas, 149,25, 0,0,255,255, 16);
+ _assertPixelApprox(canvas, 151,25, 255,255,0,255, 16);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html
new file mode 100644
index 0000000000..c26c8ecb78
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.overlap2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.overlap2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
+ for (var p = 0; p < ps.length; ++p)
+ {
+ g.addColorStop(ps[p], '#0f0');
+ for (var i = 0; i < 15; ++i)
+ g.addColorStop(ps[p], '#f00');
+ g.addColorStop(ps[p], '#0f0');
+ }
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 30,25, 0,255,0,255);
+ _assertPixel(canvas, 40,25, 0,255,0,255);
+ _assertPixel(canvas, 60,25, 0,255,0,255);
+ _assertPixel(canvas, 80,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.worker.js
new file mode 100644
index 0000000000..3938081cef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.overlap2.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.overlap2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
+ for (var p = 0; p < ps.length; ++p)
+ {
+ g.addColorStop(ps[p], '#0f0');
+ for (var i = 0; i < 15; ++i)
+ g.addColorStop(ps[p], '#f00');
+ g.addColorStop(ps[p], '#0f0');
+ }
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 30,25, 0,255,0,255);
+ _assertPixel(canvas, 40,25, 0,255,0,255);
+ _assertPixel(canvas, 60,25, 0,255,0,255);
+ _assertPixel(canvas, 80,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.html
new file mode 100644
index 0000000000..dd369ae5e3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.solid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.solid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.worker.js
new file mode 100644
index 0000000000..387aab0ab7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.solid.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.solid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html
new file mode 100644
index 0000000000..dff5708f05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.vertical</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.vertical</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,12, 191,191,63,255, 10);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 5);
+ _assertPixelApprox(canvas, 50,37, 63,63,191,255, 10);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.png b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.png
new file mode 100644
index 0000000000..37d6a00c62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.worker.js
new file mode 100644
index 0000000000..61cf9b6d8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.vertical.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.vertical
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,12, 191,191,63,255, 10);
+ _assertPixelApprox(canvas, 50,25, 127,127,127,255, 5);
+ _assertPixelApprox(canvas, 50,37, 63,63,191,255, 10);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html
new file mode 100644
index 0000000000..27579fc829
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.zerosize.fill</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.zerosize.fill</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ _assertPixel(canvas, 40,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.worker.js
new file mode 100644
index 0000000000..916b1cb977
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fill.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.zerosize.fill
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ _assertPixel(canvas, 40,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html
new file mode 100644
index 0000000000..9cf2c7350f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.zerosize.fillRect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.zerosize.fillRect</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 40,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.worker.js
new file mode 100644
index 0000000000..607ad85ae7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.zerosize.fillRect
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 40,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html
new file mode 100644
index 0000000000..59f0964461
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.zerosize.fillText</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.zerosize.fillText</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.fillText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.worker.js
new file mode 100644
index 0000000000..417b564e6d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.zerosize.fillText
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.fillText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html
new file mode 100644
index 0000000000..562f46796c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.zerosize.stroke</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.zerosize.stroke</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.rect(20, 20, 60, 10);
+ ctx.stroke();
+ _assertPixel(canvas, 19,19, 0,255,0,255);
+ _assertPixel(canvas, 20,19, 0,255,0,255);
+ _assertPixel(canvas, 21,19, 0,255,0,255);
+ _assertPixel(canvas, 19,20, 0,255,0,255);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ _assertPixel(canvas, 21,20, 0,255,0,255);
+ _assertPixel(canvas, 19,21, 0,255,0,255);
+ _assertPixel(canvas, 20,21, 0,255,0,255);
+ _assertPixel(canvas, 21,21, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.worker.js
new file mode 100644
index 0000000000..b969be6f85
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.stroke.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.zerosize.stroke
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.rect(20, 20, 60, 10);
+ ctx.stroke();
+ _assertPixel(canvas, 19,19, 0,255,0,255);
+ _assertPixel(canvas, 20,19, 0,255,0,255);
+ _assertPixel(canvas, 21,19, 0,255,0,255);
+ _assertPixel(canvas, 19,20, 0,255,0,255);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ _assertPixel(canvas, 21,20, 0,255,0,255);
+ _assertPixel(canvas, 19,21, 0,255,0,255);
+ _assertPixel(canvas, 20,21, 0,255,0,255);
+ _assertPixel(canvas, 21,21, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html
new file mode 100644
index 0000000000..de1e57bbcc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.zerosize.strokeRect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.zerosize.strokeRect</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.strokeRect(20, 20, 60, 10);
+ _assertPixel(canvas, 19,19, 0,255,0,255);
+ _assertPixel(canvas, 20,19, 0,255,0,255);
+ _assertPixel(canvas, 21,19, 0,255,0,255);
+ _assertPixel(canvas, 19,20, 0,255,0,255);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ _assertPixel(canvas, 21,20, 0,255,0,255);
+ _assertPixel(canvas, 19,21, 0,255,0,255);
+ _assertPixel(canvas, 20,21, 0,255,0,255);
+ _assertPixel(canvas, 21,21, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.worker.js
new file mode 100644
index 0000000000..b9884d4adf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeRect.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.zerosize.strokeRect
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.strokeRect(20, 20, 60, 10);
+ _assertPixel(canvas, 19,19, 0,255,0,255);
+ _assertPixel(canvas, 20,19, 0,255,0,255);
+ _assertPixel(canvas, 21,19, 0,255,0,255);
+ _assertPixel(canvas, 19,20, 0,255,0,255);
+ _assertPixel(canvas, 20,20, 0,255,0,255);
+ _assertPixel(canvas, 21,20, 0,255,0,255);
+ _assertPixel(canvas, 19,21, 0,255,0,255);
+ _assertPixel(canvas, 20,21, 0,255,0,255);
+ _assertPixel(canvas, 21,21, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html
new file mode 100644
index 0000000000..153ec102ac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.interpolate.zerosize.strokeText</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.interpolate.zerosize.strokeText</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.strokeText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.worker.js
new file mode 100644
index 0000000000..f0d7192627
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.interpolate.zerosize.strokeText
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.strokeText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html
new file mode 100644
index 0000000000..6c8f8ec38a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.linear.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.linear.nonfinite</h1>
+<p class="desc">createLinearGradient() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("createLinearGradient() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(-Infinity, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(NaN, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, -Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, NaN, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, -Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, NaN, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, Infinity, Infinity); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.worker.js
new file mode 100644
index 0000000000..9fd4949d7d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.nonfinite.worker.js
@@ -0,0 +1,44 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.linear.nonfinite
+// Description:createLinearGradient() throws TypeError if arguments are not finite
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createLinearGradient() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(-Infinity, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(NaN, 0, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, -Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, NaN, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, -Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, NaN, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, 1, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, 1, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, Infinity, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(Infinity, 0, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, Infinity, 0); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, Infinity, 1, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createLinearGradient(0, 0, Infinity, Infinity); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.html
new file mode 100644
index 0000000000..69fc52cedd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.linear.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.linear.transform.1</h1>
+<p class="desc">Linear gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<script>
+var t = async_test("Linear gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.worker.js
new file mode 100644
index 0000000000..79cdc96da8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.1.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.linear.transform.1
+// Description:Linear gradient coordinates are relative to the coordinate space at the time of filling
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Linear gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.html
new file mode 100644
index 0000000000..5cf27f1d8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.linear.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.linear.transform.2</h1>
+<p class="desc">Linear gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<script>
+var t = async_test("Linear gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(100, 0);
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-150, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.worker.js
new file mode 100644
index 0000000000..a2b532d1f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.2.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.linear.transform.2
+// Description:Linear gradient coordinates are relative to the coordinate space at the time of filling
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Linear gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(100, 0);
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-150, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.html
new file mode 100644
index 0000000000..074722a49b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.linear.transform.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.linear.transform.3</h1>
+<p class="desc">Linear gradient transforms do not experience broken caching effects</p>
+
+
+<script>
+var t = async_test("Linear gradient transforms do not experience broken caching effects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.worker.js
new file mode 100644
index 0000000000..77df9495c3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.linear.transform.3.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.linear.transform.3
+// Description:Linear gradient transforms do not experience broken caching effects
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Linear gradient transforms do not experience broken caching effects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.html
new file mode 100644
index 0000000000..d923a2f552
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.object.compare</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.object.compare</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ var g2 = ctx.createLinearGradient(0, 0, 100, 0);
+ _assertDifferent(g1, g2, "g1", "g2");
+ ctx.fillStyle = g1;
+ _assertSame(ctx.fillStyle, g1, "ctx.fillStyle", "g1");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.worker.js
new file mode 100644
index 0000000000..f6d45d259f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.compare.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.object.compare
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ var g2 = ctx.createLinearGradient(0, 0, 100, 0);
+ _assertDifferent(g1, g2, "g1", "g2");
+ ctx.fillStyle = g1;
+ _assertSame(ctx.fillStyle, g1, "ctx.fillStyle", "g1");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html
new file mode 100644
index 0000000000..6d229ea3d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.object.crosscanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.object.crosscanvas</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = new OffscreenCanvas(100, 50).getContext('2d').createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.worker.js
new file mode 100644
index 0000000000..1afebdea1b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.crosscanvas.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.object.crosscanvas
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = new OffscreenCanvas(100, 50).getContext('2d').createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html
new file mode 100644
index 0000000000..3db5afeeb5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.object.invalidcolor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.object.invalidcolor</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, ""); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'null'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'undefined'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, null); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, undefined); });
+
+ var g = ctx.createRadialGradient(0, 0, 0, 100, 0, 0);
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, ""); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'null'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'undefined'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, null); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, undefined); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.worker.js
new file mode 100644
index 0000000000..33b524fbed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidcolor.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.object.invalidcolor
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, ""); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'null'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'undefined'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, null); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, undefined); });
+
+ var g = ctx.createRadialGradient(0, 0, 0, 100, 0, 0);
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, ""); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'null'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, 'undefined'); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, null); });
+ assert_throws_dom("SYNTAX_ERR", function() { g.addColorStop(0, undefined); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html
new file mode 100644
index 0000000000..b9f1104254
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.object.invalidoffset</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.object.invalidoffset</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ assert_throws_dom("INDEX_SIZE_ERR", function() { g.addColorStop(-1, '#000'); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { g.addColorStop(2, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(Infinity, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(-Infinity, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(NaN, '#000'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.worker.js
new file mode 100644
index 0000000000..80be64235b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.invalidoffset.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.object.invalidoffset
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ assert_throws_dom("INDEX_SIZE_ERR", function() { g.addColorStop(-1, '#000'); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { g.addColorStop(2, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(Infinity, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(-Infinity, '#000'); });
+ assert_throws_js(TypeError, function() { g.addColorStop(NaN, '#000'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.html
new file mode 100644
index 0000000000..779b941d20
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.object.return</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.object.return</h1>
+<p class="desc">createLinearGradient() and createRadialGradient() returns objects implementing CanvasGradient</p>
+
+
+<script>
+var t = async_test("createLinearGradient() and createRadialGradient() returns objects implementing CanvasGradient");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ window.CanvasGradient.prototype.thisImplementsCanvasGradient = true;
+
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ _assertDifferent(g1.addColorStop, undefined, "g1.addColorStop", "undefined");
+ _assertSame(g1.thisImplementsCanvasGradient, true, "g1.thisImplementsCanvasGradient", "true");
+
+ var g2 = ctx.createRadialGradient(0, 0, 10, 0, 0, 20);
+ _assertDifferent(g2.addColorStop, undefined, "g2.addColorStop", "undefined");
+ _assertSame(g2.thisImplementsCanvasGradient, true, "g2.thisImplementsCanvasGradient", "true");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.worker.js
new file mode 100644
index 0000000000..a279eed4f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.return.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.object.return
+// Description:createLinearGradient() and createRadialGradient() returns objects implementing CanvasGradient
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createLinearGradient() and createRadialGradient() returns objects implementing CanvasGradient");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ self.CanvasGradient.prototype.thisImplementsCanvasGradient = true;
+
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ _assertDifferent(g1.addColorStop, undefined, "g1.addColorStop", "undefined");
+ _assertSame(g1.thisImplementsCanvasGradient, true, "g1.thisImplementsCanvasGradient", "true");
+
+ var g2 = ctx.createRadialGradient(0, 0, 10, 0, 0, 20);
+ _assertDifferent(g2.addColorStop, undefined, "g2.addColorStop", "undefined");
+ _assertSame(g2.thisImplementsCanvasGradient, true, "g2.thisImplementsCanvasGradient", "true");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.html
new file mode 100644
index 0000000000..aa72183ca5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.object.type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.object.type</h1>
+<p class="desc">window.CanvasGradient exists and has the right properties</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("window.CanvasGradient exists and has the right properties");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(window.CanvasGradient, undefined, "window.CanvasGradient", "undefined");
+ _assertDifferent(window.CanvasGradient.prototype.addColorStop, undefined, "window.CanvasGradient.prototype.addColorStop", "undefined");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.worker.js
new file mode 100644
index 0000000000..e0101dfca4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.type.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.object.type
+// Description:window.CanvasGradient exists and has the right properties
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("window.CanvasGradient exists and has the right properties");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(self.CanvasGradient, undefined, "self.CanvasGradient", "undefined");
+ _assertDifferent(self.CanvasGradient.prototype.addColorStop, undefined, "self.CanvasGradient.prototype.addColorStop", "undefined");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.html
new file mode 100644
index 0000000000..00c60041e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.object.update</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.object.update</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(-100, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ g.addColorStop(0.1, '#0f0');
+ g.addColorStop(0.9, '#0f0');
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.worker.js
new file mode 100644
index 0000000000..db79ebfa2f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.object.update.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.object.update
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createLinearGradient(-100, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ g.addColorStop(0.1, '#0f0');
+ g.addColorStop(0.9, '#0f0');
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html
new file mode 100644
index 0000000000..c270a75175
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.behind</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.behind</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.worker.js
new file mode 100644
index 0000000000..07ea409ad8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.behind.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.behind
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html
new file mode 100644
index 0000000000..89d8757bde
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.beside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.beside</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.worker.js
new file mode 100644
index 0000000000..686721cbc6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.beside.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.beside
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html
new file mode 100644
index 0000000000..cda6743f66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.bottom</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.bottom</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.worker.js
new file mode 100644
index 0000000000..c96b9c59f2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.bottom.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.bottom
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html
new file mode 100644
index 0000000000..a6f1d67619
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.cylinder</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.cylinder</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.worker.js
new file mode 100644
index 0000000000..22e6cb49ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.cylinder.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.cylinder
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.html
new file mode 100644
index 0000000000..5cda039e94
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.front</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.front</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.worker.js
new file mode 100644
index 0000000000..c4e70f53c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.front.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.front
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html
new file mode 100644
index 0000000000..290923b5e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.shape1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.shape1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(30+tol, 40);
+ ctx.lineTo(110, -20+tol);
+ ctx.lineTo(110, 100-tol);
+ ctx.fill();
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.worker.js
new file mode 100644
index 0000000000..d03c0db23c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape1.worker.js
@@ -0,0 +1,48 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.shape1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(30+tol, 40);
+ ctx.lineTo(110, -20+tol);
+ ctx.lineTo(110, 100-tol);
+ ctx.fill();
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html
new file mode 100644
index 0000000000..edf1909ac1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.shape2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.shape2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(30-tol, 40);
+ ctx.lineTo(110, -20-tol);
+ ctx.lineTo(110, 100+tol);
+ ctx.fill();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.worker.js
new file mode 100644
index 0000000000..8788954a3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.worker.js
@@ -0,0 +1,48 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.shape2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(30-tol, 40);
+ ctx.lineTo(110, -20-tol);
+ ctx.lineTo(110, 100+tol);
+ ctx.fill();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.html
new file mode 100644
index 0000000000..9487c8c931
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.cone.top</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.cone.top</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.worker.js
new file mode 100644
index 0000000000..6fc834373a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.cone.top.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.cone.top
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.html
new file mode 100644
index 0000000000..b14b44fe30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.equal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.equal</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.worker.js
new file mode 100644
index 0000000000..c8e6095805
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.equal.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.equal
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.html
new file mode 100644
index 0000000000..a55f0a1104
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.inside1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.inside1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.worker.js
new file mode 100644
index 0000000000..5da290a7ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside1.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.inside1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.html
new file mode 100644
index 0000000000..3a7af0658b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.inside2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.inside2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.worker.js
new file mode 100644
index 0000000000..dd49fa3771
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside2.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.inside2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.html
new file mode 100644
index 0000000000..3a539e6b63
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.inside3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.inside3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.993, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.worker.js
new file mode 100644
index 0000000000..0d05bf4d5b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.inside3.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.inside3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.993, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.html
new file mode 100644
index 0000000000..b6dcaf175e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.negative</h1>
+<p class="desc">createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative</p>
+
+
+<script>
+var t = async_test("createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.worker.js
new file mode 100644
index 0000000000..72ad3f803e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.negative.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.negative
+// Description:createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html
new file mode 100644
index 0000000000..4f068bbda5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.nonfinite</h1>
+<p class="desc">createRadialGradient() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("createRadialGradient() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, NaN, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, NaN, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, NaN, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, NaN, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.worker.js
new file mode 100644
index 0000000000..641a341ecc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.nonfinite.worker.js
@@ -0,0 +1,96 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.nonfinite
+// Description:createRadialGradient() throws TypeError if arguments are not finite
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createRadialGradient() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, NaN, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, NaN, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, NaN, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, NaN, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, 0, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.html
new file mode 100644
index 0000000000..2643c67170
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.outside1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.outside1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.worker.js
new file mode 100644
index 0000000000..52d45093ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside1.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.outside1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.html
new file mode 100644
index 0000000000..423de4491d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.outside2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.outside2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.worker.js
new file mode 100644
index 0000000000..861dcccbe3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside2.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.outside2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.html
new file mode 100644
index 0000000000..61df3dccfe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.outside3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.outside3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.001, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.worker.js
new file mode 100644
index 0000000000..db65ea1b8b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.outside3.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.outside3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.001, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.html
new file mode 100644
index 0000000000..86e2af1428
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.touch1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.touch1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.worker.js
new file mode 100644
index 0000000000..dd8d727209
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch1.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.touch1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.html
new file mode 100644
index 0000000000..b0ff86ad05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.touch2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.touch2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.01, '#0f0');
+ g.addColorStop(0.99, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.worker.js
new file mode 100644
index 0000000000..ad6bc9d897
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch2.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.touch2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.01, '#0f0');
+ g.addColorStop(0.99, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.html
new file mode 100644
index 0000000000..5e085fd998
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.touch3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.touch3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.worker.js
new file mode 100644
index 0000000000..540e9a7ed4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.touch3.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.touch3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 1);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixelApprox(canvas, 50,48, 0,255,0,255, 1);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.html
new file mode 100644
index 0000000000..517c9e3288
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.transform.1</h1>
+<p class="desc">Radial gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<script>
+var t = async_test("Radial gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.worker.js
new file mode 100644
index 0000000000..198dab1fce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.1.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.transform.1
+// Description:Radial gradient coordinates are relative to the coordinate space at the time of filling
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Radial gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.html
new file mode 100644
index 0000000000..f7f4120a92
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.transform.2</h1>
+<p class="desc">Radial gradient coordinates are relative to the coordinate space at the time of filling</p>
+
+
+<script>
+var t = async_test("Radial gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(100, 0);
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.worker.js
new file mode 100644
index 0000000000..27793b90ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.2.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.transform.2
+// Description:Radial gradient coordinates are relative to the coordinate space at the time of filling
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Radial gradient coordinates are relative to the coordinate space at the time of filling");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(100, 0);
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.html
new file mode 100644
index 0000000000..e0ac17fa82
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.gradient.radial.transform.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.gradient.radial.transform.3</h1>
+<p class="desc">Radial gradient transforms do not experience broken caching effects</p>
+
+
+<script>
+var t = async_test("Radial gradient transforms do not experience broken caching effects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.worker.js
new file mode 100644
index 0000000000..1b74d8b4d7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.radial.transform.3.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.gradient.radial.transform.3
+// Description:Radial gradient transforms do not experience broken caching effects
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Radial gradient transforms do not experience broken caching effects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.html
new file mode 100644
index 0000000000..f82a259e43
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.basic.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.basic.canvas</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.worker.js
new file mode 100644
index 0000000000..510723f009
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.canvas.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.basic.canvas
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.html
new file mode 100644
index 0000000000..ab7b7bbeb5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.basic.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.basic.image</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.worker.js
new file mode 100644
index 0000000000..14cfcbc993
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.image.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.basic.image
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.html
new file mode 100644
index 0000000000..66e301a002
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.basic.nocontext</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.basic.nocontext</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.js
new file mode 100644
index 0000000000..f6c24c82ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.nocontext.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.basic.nocontext
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.html
new file mode 100644
index 0000000000..1edb4fd227
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.basic.type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.basic.type</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(window.CanvasPattern, undefined, "window.CanvasPattern", "undefined");
+
+ window.CanvasPattern.prototype.thisImplementsCanvasPattern = true;
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ _assert(pattern.thisImplementsCanvasPattern, "pattern.thisImplementsCanvasPattern");
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.worker.js
new file mode 100644
index 0000000000..56a8a7d23c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.type.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.basic.type
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(self.CanvasPattern, undefined, "self.CanvasPattern", "undefined");
+
+ self.CanvasPattern.prototype.thisImplementsCanvasPattern = true;
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ _assert(pattern.thisImplementsCanvasPattern, "pattern.thisImplementsCanvasPattern");
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html
new file mode 100644
index 0000000000..7100c8313f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.basic.zerocanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.basic.zerocanvas</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 0;
+ canvas.height = 10;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 10, "canvas.height", "10");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+
+ canvas.width = 10;
+ canvas.height = 0;
+ _assertSame(canvas.width, 10, "canvas.width", "10");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+
+ canvas.width = 0;
+ canvas.height = 0;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.worker.js
new file mode 100644
index 0000000000..9bf487cf74
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.basic.zerocanvas.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.basic.zerocanvas
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 0;
+ canvas.height = 10;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 10, "canvas.height", "10");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+
+ canvas.width = 10;
+ canvas.height = 0;
+ _assertSame(canvas.width, 10, "canvas.width", "10");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+
+ canvas.width = 0;
+ canvas.height = 0;
+ _assertSame(canvas.width, 0, "canvas.width", "0");
+ _assertSame(canvas.height, 0, "canvas.height", "0");
+ assert_throws_dom("INVALID_STATE_ERR", function() { ctx.createPattern(canvas, 'repeat'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.html
new file mode 100644
index 0000000000..bdf89021bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.crosscanvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.crosscanvas</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+
+ var pattern = new OffscreenCanvas(100, 50).getContext('2d').createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.worker.js
new file mode 100644
index 0000000000..d9004fc028
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.crosscanvas.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.crosscanvas
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+
+ var pattern = new OffscreenCanvas(100, 50).getContext('2d').createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.html
new file mode 100644
index 0000000000..fbec25862d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.image.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.image.null</h1>
+<p class="desc"></p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createPattern(null, 'repeat'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.worker.js
new file mode 100644
index 0000000000..a68ddfdbd7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.null.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.image.null
+// Description:
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createPattern(null, 'repeat'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.html
new file mode 100644
index 0000000000..ff7355d2a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.image.string</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.image.string</h1>
+<p class="desc"></p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createPattern('../images/red.png', 'repeat'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.worker.js
new file mode 100644
index 0000000000..dc53d82292
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.string.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.image.string
+// Description:
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createPattern('../images/red.png', 'repeat'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.html
new file mode 100644
index 0000000000..845f823e7f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.image.undefined</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.image.undefined</h1>
+<p class="desc"></p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createPattern(undefined, 'repeat'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.worker.js
new file mode 100644
index 0000000000..32f5749493
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.image.undefined.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.image.undefined
+// Description:
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createPattern(undefined, 'repeat'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.html
new file mode 100644
index 0000000000..ebeb92c7f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.modify.canvas1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.modify.canvas1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.worker.js
new file mode 100644
index 0000000000..8e4f9ed447
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas1.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.modify.canvas1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.html
new file mode 100644
index 0000000000..042ebba3b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.modify.canvas2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.modify.canvas2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.worker.js
new file mode 100644
index 0000000000..ed17db8127
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.modify.canvas2.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.modify.canvas2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html
new file mode 100644
index 0000000000..8ab1c8eb40
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.norepeat.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.norepeat.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.worker.js
new file mode 100644
index 0000000000..9ac4e1605c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.basic.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.norepeat.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html
new file mode 100644
index 0000000000..4bdd356df7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.norepeat.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.norepeat.coord1</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.worker.js
new file mode 100644
index 0000000000..6c4a1409b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord1.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.norepeat.coord1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html
new file mode 100644
index 0000000000..b9164ec6a9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.norepeat.coord2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.norepeat.coord2</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.worker.js
new file mode 100644
index 0000000000..d2fdd86022
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord2.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.norepeat.coord2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/green.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html
new file mode 100644
index 0000000000..e2983948c2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.norepeat.coord3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.norepeat.coord3</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.worker.js
new file mode 100644
index 0000000000..584a5d6cfd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.coord3.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.norepeat.coord3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html
new file mode 100644
index 0000000000..43a718d44a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.norepeat.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.norepeat.outside</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+ ctx.fillRect(-100, 0, 100, 50);
+ ctx.fillRect(0, 50, 100, 50);
+ ctx.fillRect(100, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.worker.js
new file mode 100644
index 0000000000..0b5fef95ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.norepeat.outside.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.norepeat.outside
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+ ctx.fillRect(-100, 0, 100, 50);
+ ctx.fillRect(0, 50, 100, 50);
+ ctx.fillRect(100, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html
new file mode 100644
index 0000000000..b63535c706
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.orientation.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.orientation.canvas</h1>
+<p class="desc">Canvas patterns do not get flipped when painted</p>
+
+
+<script>
+var t = async_test("Canvas patterns do not get flipped when painted");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 25);
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 25, 100, 25);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.worker.js
new file mode 100644
index 0000000000..2fbe52af73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.canvas.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.orientation.canvas
+// Description:Canvas patterns do not get flipped when painted
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Canvas patterns do not get flipped when painted");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 25);
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 25, 100, 25);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html
new file mode 100644
index 0000000000..0b3645981e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.orientation.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.orientation.image</h1>
+<p class="desc">Image patterns do not get flipped when painted</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/rrgg-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.save();
+ ctx.translate(0, -103);
+ ctx.fillRect(0, 103, 100, 50);
+ ctx.restore();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "Image patterns do not get flipped when painted");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.worker.js
new file mode 100644
index 0000000000..b303b2d813
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.orientation.image.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.orientation.image
+// Description:Image patterns do not get flipped when painted
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/rrgg-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.save();
+ ctx.translate(0, -103);
+ ctx.fillRect(0, 103, 100, 50);
+ ctx.restore();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "Image patterns do not get flipped when painted");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html
new file mode 100644
index 0000000000..b6647f776e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeat.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeat.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.worker.js
new file mode 100644
index 0000000000..37f4c04228
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.basic.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeat.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html
new file mode 100644
index 0000000000..54b24ac705
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeat.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeat.coord1</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/rgrg-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.worker.js
new file mode 100644
index 0000000000..efbd1c5846
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord1.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeat.coord1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/rgrg-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html
new file mode 100644
index 0000000000..a77ce2c696
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeat.coord2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeat.coord2</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/ggrr-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.worker.js
new file mode 100644
index 0000000000..db707ecb0a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord2.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeat.coord2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/ggrr-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html
new file mode 100644
index 0000000000..10f380fed3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeat.coord3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeat.coord3</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/rgrg-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.worker.js
new file mode 100644
index 0000000000..e58cddccfe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.coord3.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeat.coord3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/rgrg-256x256.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html
new file mode 100644
index 0000000000..6558e07c5b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeat.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeat.outside</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.worker.js
new file mode 100644
index 0000000000..4a173af0b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeat.outside.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeat.outside
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html
new file mode 100644
index 0000000000..494b72cfb9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeatx.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeatx.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 16);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.worker.js
new file mode 100644
index 0000000000..e776f7a008
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.basic.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeatx.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 16);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html
new file mode 100644
index 0000000000..6caef0cb1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeatx.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeatx.coord1</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.translate(0, 16);
+ ctx.fillRect(0, -16, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.worker.js
new file mode 100644
index 0000000000..57c2102cc8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.coord1.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeatx.coord1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.translate(0, 16);
+ ctx.fillRect(0, -16, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html
new file mode 100644
index 0000000000..b3229c8d87
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeatx.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeatx.outside</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.worker.js
new file mode 100644
index 0000000000..e40f6aa207
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeatx.outside.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeatx.outside
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html
new file mode 100644
index 0000000000..d88f3a0ab6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeaty.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeaty.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 50);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.worker.js
new file mode 100644
index 0000000000..6a53b5dc4d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.basic.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeaty.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 50);
+
+ var response = await fetch('/images/green-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html
new file mode 100644
index 0000000000..59bfeb2abf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeaty.coord1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeaty.coord1</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.translate(48, 0);
+ ctx.fillRect(-48, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.worker.js
new file mode 100644
index 0000000000..d59abb6e07
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.coord1.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeaty.coord1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.translate(48, 0);
+ ctx.fillRect(-48, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html
new file mode 100644
index 0000000000..ad2bd3383f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.paint.repeaty.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.paint.repeaty.outside</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.worker.js
new file mode 100644
index 0000000000..c4feba10ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.paint.repeaty.outside.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.paint.repeaty.outside
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var response = await fetch('/images/red-16x16.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.html
new file mode 100644
index 0000000000..377ae3edc4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.repeat.case</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.repeat.case</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "Repeat"); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.worker.js
new file mode 100644
index 0000000000..8073f47ed0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.case.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.repeat.case
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "Repeat"); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.html
new file mode 100644
index 0000000000..c2197893d7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.repeat.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.repeat.empty</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var response = await fetch('/images/green-1x1.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, "");
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 200, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.worker.js
new file mode 100644
index 0000000000..5aefc0dab3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.empty.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.repeat.empty
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var response = await fetch('/images/green-1x1.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, "");
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 200, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.html
new file mode 100644
index 0000000000..d79551a302
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.repeat.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.repeat.null</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assert(ctx.createPattern(canvas, null) != null, "ctx.createPattern(canvas, null) != null");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.worker.js
new file mode 100644
index 0000000000..6ab4da9f8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.null.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.repeat.null
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assert(ctx.createPattern(canvas, null) != null, "ctx.createPattern(canvas, null) != null");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html
new file mode 100644
index 0000000000..2f4a35dedf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.repeat.nullsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.repeat.nullsuffix</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "repeat\0"); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.worker.js
new file mode 100644
index 0000000000..83e7c62fe5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.nullsuffix.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.repeat.nullsuffix
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "repeat\0"); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.html
new file mode 100644
index 0000000000..8ddd231985
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.repeat.undefined</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.repeat.undefined</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, undefined); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.worker.js
new file mode 100644
index 0000000000..f4f25ae5a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.undefined.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.repeat.undefined
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, undefined); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html
new file mode 100644
index 0000000000..3a37b46ab7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.repeat.unrecognised</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.repeat.unrecognised</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "invalid"); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.worker.js
new file mode 100644
index 0000000000..3114dde21a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognised.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.repeat.unrecognised
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "invalid"); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html
new file mode 100644
index 0000000000..58fb005d70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.repeat.unrecognisednull</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.repeat.unrecognisednull</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "null"); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.worker.js
new file mode 100644
index 0000000000..c8d18511f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.repeat.unrecognisednull.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.repeat.unrecognisednull
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("SYNTAX_ERR", function() { ctx.createPattern(canvas, "null"); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.html
new file mode 100644
index 0000000000..2d73296395
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.transform.identity</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.transform.identity</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform(new DOMMatrix());
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.worker.js
new file mode 100644
index 0000000000..a33c771346
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.identity.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.transform.identity
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform(new DOMMatrix());
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.html
new file mode 100644
index 0000000000..aa58ad119f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.transform.infinity</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.transform.infinity</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform({a: Infinity});
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.worker.js
new file mode 100644
index 0000000000..999739b848
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.infinity.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.transform.infinity
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform({a: Infinity});
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.html
new file mode 100644
index 0000000000..f2420d4a2b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.pattern.transform.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.pattern.transform.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ assert_throws_js(TypeError, function() { pattern.setTransform({a: 1, m11: 2}); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.worker.js
new file mode 100644
index 0000000000..163951807f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.pattern.transform.invalid.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.pattern.transform.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ assert_throws_js(TypeError, function() { pattern.setTransform({a: 1, m11: 2}); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.colormix.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.colormix.html
new file mode 100644
index 0000000000..eba026619a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.colormix.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeStyle.colormix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeStyle.colormix</h1>
+<p class="desc">color-mix works as color input</p>
+
+
+<script>
+var t = async_test("color-mix works as color input");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = "color-mix(in srgb, red, blue)";
+ _assertSame(ctx.strokeStyle, 'color(srgb 0.5 0 0.5)', "ctx.strokeStyle", "'color(srgb 0.5 0 0.5)'");
+ ctx.strokeStyle = "color-mix(in srgb, red, color(srgb 1 0 0))";
+ _assertSame(ctx.strokeStyle, 'color(srgb 1 0 0)', "ctx.strokeStyle", "'color(srgb 1 0 0)'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.html b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.html
new file mode 100644
index 0000000000..cd7e424374
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.strokeStyle.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.strokeStyle.default</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.strokeStyle, '#000000', "ctx.strokeStyle", "'#000000'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.worker.js
new file mode 100644
index 0000000000..9e0ac8be3e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.strokeStyle.default.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.strokeStyle.default
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.strokeStyle, '#000000', "ctx.strokeStyle", "'#000000'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html
new file mode 100644
index 0000000000..d8f14529c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.blur.exceptions.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.blur.exceptions.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() blur.object</p>
+
+
+<script>
+var t = async_test("Test exceptions on CanvasFilter() blur.object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur'}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}}); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js
new file mode 100644
index 0000000000..9b3fb3c04c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.blur.exceptions.tentative
+// Description:Test exceptions on CanvasFilter() blur.object
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test exceptions on CanvasFilter() blur.object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur'}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN}); });
+ assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}}); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html
new file mode 100644
index 0000000000..242094d9f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.colorMatrix.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.colorMatrix.tentative</h1>
+<p class="desc">Test the functionality of ColorMatrix filters in CanvasFilter objects</p>
+
+
+<script>
+var t = async_test("Test the functionality of ColorMatrix filters in CanvasFilter objects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: 'foo'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}); });
+ ctx.fillStyle = '#f00';
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [
+ 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0
+ ]});
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 25);
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 25, 50, 25);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(50, 25, 50, 25);
+ _assertPixelApprox(canvas, 10,10, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 60,10, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 10,30, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 60,30, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js
new file mode 100644
index 0000000000..d214e1d836
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js
@@ -0,0 +1,64 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.colorMatrix.tentative
+// Description:Test the functionality of ColorMatrix filters in CanvasFilter objects
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test the functionality of ColorMatrix filters in CanvasFilter objects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: 'foo'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}); });
+ ctx.fillStyle = '#f00';
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2);
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'});
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [
+ 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0
+ ]});
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 25);
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 25, 50, 25);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(50, 25, 50, 25);
+ _assertPixelApprox(canvas, 10,10, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 60,10, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 10,30, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 60,30, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html
new file mode 100644
index 0000000000..ff1de6bc9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p>
+
+
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with discrete type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k];
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'discrete', tableValues: tableValuesR},
+ funcG: {type: 'discrete', tableValues: tableValuesG},
+ funcB: {type: 'discrete', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.worker.js
new file mode 100644
index 0000000000..0e68f4899f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.worker.js
@@ -0,0 +1,62 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.discrete.tentative
+// Description:Test pixels on CanvasFilter() componentTransfer with discrete type
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with discrete type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k];
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'discrete', tableValues: tableValuesR},
+ funcG: {type: 'discrete', tableValues: tableValuesG},
+ funcB: {type: 'discrete', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html
new file mode 100644
index 0000000000..64c30fc417
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p>
+
+
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with gamma type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, amplitude, exponent, offset) {
+ return [
+ Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255,
+ ];
+ }
+
+ const amplitudes = [2, 1.1, 0.5];
+ const exponents = [5, 3, 1];
+ const offsets = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]},
+ funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]},
+ funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, amplitudes, exponents, offsets);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.worker.js
new file mode 100644
index 0000000000..d59bc699df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.worker.js
@@ -0,0 +1,53 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.gamma.tentative
+// Description:Test pixels on CanvasFilter() componentTransfer with gamma type
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with gamma type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, amplitude, exponent, offset) {
+ return [
+ Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255,
+ ];
+ }
+
+ const amplitudes = [2, 1.1, 0.5];
+ const exponents = [5, 3, 1];
+ const offsets = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]},
+ funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]},
+ funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, amplitudes, exponents, offsets);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html
new file mode 100644
index 0000000000..e0d628952e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.identity.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p>
+
+
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with identity type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'identity'},
+ funcG: {type: 'identity'},
+ funcB: {type: 'identity'},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`,
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255);
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.worker.js
new file mode 100644
index 0000000000..1b714b58ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.identity.tentative
+// Description:Test pixels on CanvasFilter() componentTransfer with identity type
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with identity type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'identity'},
+ funcG: {type: 'identity'},
+ funcB: {type: 'identity'},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`,
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255);
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html
new file mode 100644
index 0000000000..adbe557fd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.linear.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p>
+
+
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with linear type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, slopes, intercepts) {
+ return [
+ Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255,
+ Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255,
+ Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255,
+ ];
+ }
+
+ const slopes = [0.5, 1.2, -0.2];
+ const intercepts = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]},
+ funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]},
+ funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, slopes, intercepts);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.worker.js
new file mode 100644
index 0000000000..fb2e01876f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.worker.js
@@ -0,0 +1,52 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.linear.tentative
+// Description:Test pixels on CanvasFilter() componentTransfer with linear type
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with linear type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, slopes, intercepts) {
+ return [
+ Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255,
+ Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255,
+ Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255,
+ ];
+ }
+
+ const slopes = [0.5, 1.2, -0.2];
+ const intercepts = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]},
+ funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]},
+ funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, slopes, intercepts);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html
new file mode 100644
index 0000000000..47048b68a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.componentTransfer.table.tentative</h1>
+<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p>
+
+
+<script>
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with table type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length - 1;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k] + (C - k/n) * n * (V[k + 1] - V[k]);
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'table', tableValues: tableValuesR},
+ funcG: {type: 'table', tableValues: tableValuesG},
+ funcB: {type: 'table', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.worker.js
new file mode 100644
index 0000000000..0799e73a58
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.worker.js
@@ -0,0 +1,62 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.table.tentative
+// Description:Test pixels on CanvasFilter() componentTransfer with table type
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test pixels on CanvasFilter() componentTransfer with table type");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length - 1;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k] + (C - k/n) * n * (V[k + 1] - V[k]);
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'table', tableValues: tableValuesR},
+ funcG: {type: 'table', tableValues: tableValuesG},
+ funcB: {type: 'table', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html
new file mode 100644
index 0000000000..301d11f888
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() convolveMatrix</p>
+
+
+<script>
+var t = async_test("Test exceptions on CanvasFilter() convolveMatrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', divisor: 2}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); });
+ // This should not throw an error
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]});
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]});
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js
new file mode 100644
index 0000000000..b4ce4d76b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative
+// Description:Test exceptions on CanvasFilter() convolveMatrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test exceptions on CanvasFilter() convolveMatrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', divisor: 2}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); });
+ // This should not throw an error
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]});
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]});
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html
new file mode 100644
index 0000000000..3e55e97e54
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.dropShadow.exceptions.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() dropShadow object</p>
+
+
+<script>
+var t = async_test("Test exceptions on CanvasFilter() dropShadow object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // dx
+ _assert(new CanvasFilter({name: 'dropShadow', dx: 10}), "new CanvasFilter({name: 'dropShadow', dx: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: -1}), "new CanvasFilter({name: 'dropShadow', dx: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: 0.5}), "new CanvasFilter({name: 'dropShadow', dx: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: null}), "new CanvasFilter({name: 'dropShadow', dx: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: true}), "new CanvasFilter({name: 'dropShadow', dx: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: false}), "new CanvasFilter({name: 'dropShadow', dx: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: []}), "new CanvasFilter({name: 'dropShadow', dx: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: [20]}), "new CanvasFilter({name: 'dropShadow', dx: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: '30'}), "new CanvasFilter({name: 'dropShadow', dx: '30'})");
+ // dy
+ _assert(new CanvasFilter({name: 'dropShadow', dy: 10}), "new CanvasFilter({name: 'dropShadow', dy: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: -1}), "new CanvasFilter({name: 'dropShadow', dy: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: 0.5}), "new CanvasFilter({name: 'dropShadow', dy: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: null}), "new CanvasFilter({name: 'dropShadow', dy: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: true}), "new CanvasFilter({name: 'dropShadow', dy: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: false}), "new CanvasFilter({name: 'dropShadow', dy: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: []}), "new CanvasFilter({name: 'dropShadow', dy: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: [20]}), "new CanvasFilter({name: 'dropShadow', dy: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: '30'}), "new CanvasFilter({name: 'dropShadow', dy: '30'})");
+ // floodOpacity
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 10}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: -1}), "new CanvasFilter({name: 'dropShadow', floodOpacity: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: null}), "new CanvasFilter({name: 'dropShadow', floodOpacity: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: true}), "new CanvasFilter({name: 'dropShadow', floodOpacity: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: false}), "new CanvasFilter({name: 'dropShadow', floodOpacity: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: []}), "new CanvasFilter({name: 'dropShadow', floodOpacity: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: [20]}), "new CanvasFilter({name: 'dropShadow', floodOpacity: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: '30'}), "new CanvasFilter({name: 'dropShadow', floodOpacity: '30'})");
+ // stdDeviation
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({name: 'dropShadow', stdDeviation: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: null}), "new CanvasFilter({name: 'dropShadow', stdDeviation: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: true}), "new CanvasFilter({name: 'dropShadow', stdDeviation: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: false}), "new CanvasFilter({name: 'dropShadow', stdDeviation: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: []}), "new CanvasFilter({name: 'dropShadow', stdDeviation: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({name: 'dropShadow', stdDeviation: '30'})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [20]]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [\""+(20)+"\"]]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]})");
+ // floodColor
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'red'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'red'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'})");
+
+ // dx
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: [1, 2]}); });
+ // dy
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: [1, 2]}); });
+ // floodOpacity
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: [1, 2]}); });
+ // stdDeviation
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 2, 3]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, NaN]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, Infinity]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, -Infinity]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, undefined]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 'test']}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, {}]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, [2, 3]]}); });
+ // floodColor
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 10}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: NaN}); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js
new file mode 100644
index 0000000000..bd18524f28
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js
@@ -0,0 +1,119 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.dropShadow.exceptions.tentative
+// Description:Test exceptions on CanvasFilter() dropShadow object
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test exceptions on CanvasFilter() dropShadow object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // dx
+ _assert(new CanvasFilter({name: 'dropShadow', dx: 10}), "new CanvasFilter({name: 'dropShadow', dx: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: -1}), "new CanvasFilter({name: 'dropShadow', dx: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: 0.5}), "new CanvasFilter({name: 'dropShadow', dx: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: null}), "new CanvasFilter({name: 'dropShadow', dx: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: true}), "new CanvasFilter({name: 'dropShadow', dx: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: false}), "new CanvasFilter({name: 'dropShadow', dx: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: []}), "new CanvasFilter({name: 'dropShadow', dx: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: [20]}), "new CanvasFilter({name: 'dropShadow', dx: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', dx: '30'}), "new CanvasFilter({name: 'dropShadow', dx: '30'})");
+ // dy
+ _assert(new CanvasFilter({name: 'dropShadow', dy: 10}), "new CanvasFilter({name: 'dropShadow', dy: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: -1}), "new CanvasFilter({name: 'dropShadow', dy: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: 0.5}), "new CanvasFilter({name: 'dropShadow', dy: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: null}), "new CanvasFilter({name: 'dropShadow', dy: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: true}), "new CanvasFilter({name: 'dropShadow', dy: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: false}), "new CanvasFilter({name: 'dropShadow', dy: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: []}), "new CanvasFilter({name: 'dropShadow', dy: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: [20]}), "new CanvasFilter({name: 'dropShadow', dy: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', dy: '30'}), "new CanvasFilter({name: 'dropShadow', dy: '30'})");
+ // floodOpacity
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 10}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: -1}), "new CanvasFilter({name: 'dropShadow', floodOpacity: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: null}), "new CanvasFilter({name: 'dropShadow', floodOpacity: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: true}), "new CanvasFilter({name: 'dropShadow', floodOpacity: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: false}), "new CanvasFilter({name: 'dropShadow', floodOpacity: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: []}), "new CanvasFilter({name: 'dropShadow', floodOpacity: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: [20]}), "new CanvasFilter({name: 'dropShadow', floodOpacity: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: '30'}), "new CanvasFilter({name: 'dropShadow', floodOpacity: '30'})");
+ // stdDeviation
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 10})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({name: 'dropShadow', stdDeviation: -1})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: null}), "new CanvasFilter({name: 'dropShadow', stdDeviation: null})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: true}), "new CanvasFilter({name: 'dropShadow', stdDeviation: true})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: false}), "new CanvasFilter({name: 'dropShadow', stdDeviation: false})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: []}), "new CanvasFilter({name: 'dropShadow', stdDeviation: []})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [\""+(20)+"\"]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({name: 'dropShadow', stdDeviation: '30'})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [20]]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [\""+(20)+"\"]]})");
+ _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]})");
+ // floodColor
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'red'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'red'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'})");
+ _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'})");
+
+ // dx
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: [1, 2]}); });
+ // dy
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: [1, 2]}); });
+ // floodOpacity
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: [1, 2]}); });
+ // stdDeviation
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: NaN}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: -Infinity}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: {}}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 2, 3]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, NaN]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, Infinity]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, -Infinity]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, undefined]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 'test']}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, {}]}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, [2, 3]]}); });
+ // floodColor
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'test'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 10}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: undefined}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: null}); });
+ assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: NaN}); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
new file mode 100644
index 0000000000..86c5710132
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative-expected.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.dropShadow.tentative</title>
+<h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
+<p class="desc">Test CanvasFilter() dropShadow object.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width=520 height=420
+ color-interpolation-filters="sRGB">
+ <rect x=0 y=0 width=100% height=50 fill="teal" />
+ <rect x=0 y=100 width=100% height=50 fill="teal" />
+ <rect x=0 y=200 width=100% height=50 fill="teal" />
+ <rect x=0 y=300 width=100% height=50 fill="teal" />
+
+ <rect x=10 y=10 width=80 height=80 fill="crimson"
+ filter="drop-shadow(2px 2px 2px black)"/>
+ <rect x=110 y=10 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 5px rgba(128, 0, 128, 0.7))"/>
+
+ <rect x=10 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px purple)"/>
+ <rect x=110 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px LinkText)"/>
+ <rect x=210 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
+ <rect x=310 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.7))"/>
+ <rect x=410 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.49))"/>
+
+ <rect x=10 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+ <rect x=110 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 5px purple)"/>
+ <rect x=210 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+ <filter id="separable-filter"
+ x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx=9 dy=12 stdDeviation="3 5" flood-color="purple"/>
+ </filter>
+ <rect x=310 y=210 width=80 height=80 fill="crimson"
+ filter="url(#separable-filter)"/>
+ <rect x=410 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+
+ <rect x=10 y=310 width=80 height=80 fill="crimson"
+ filter="drop-shadow(-5px 0px 0px purple)"/>
+ <filter id="separable-filter-degenerate"
+ x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx=0 dy=5 stdDeviation="0 3"
+ flood-color="rgba(128, 0, 128, 0.8)"/>
+ </filter>
+ <rect x=110 y=310 width=80 height=80 fill="crimson"
+ filter="url(#separable-filter-degenerate)"/>
+ <rect x=210 y=310 width=80 height=80 fill="crimson"
+ filter="drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html
new file mode 100644
index 0000000000..81eb1eae45
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.dropShadow.tentative-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.dropShadow.tentative</title>
+<h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
+<p class="desc">Test CanvasFilter() dropShadow object.</p>
+<canvas id="canvas" width="520" height="420">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(520, 420);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(0, 0, 520, 50);
+ ctx.fillRect(0, 100, 520, 50);
+ ctx.fillRect(0, 200, 520, 50);
+ ctx.fillRect(0, 300, 520, 50);
+
+ ctx.fillStyle = 'crimson';
+
+ // Parameter defaults.
+ ctx.filter = new CanvasFilter({name: 'dropShadow'});
+ ctx.fillRect(10, 10, 80, 80);
+
+ // All parameters specified.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple', floodOpacity: 0.7});
+ ctx.fillRect(110, 10, 80, 80);
+
+ // Named color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 110, 80, 80);
+
+ // System color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'LinkText'});
+ ctx.fillRect(110, 110, 80, 80);
+
+ // Numerical color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 1)'});
+ ctx.fillRect(210, 110, 80, 80);
+
+ // Transparent floodColor.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)'});
+ ctx.fillRect(310, 110, 80, 80);
+
+ // Transparent floodColor and floodOpacity.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7});
+ ctx.fillRect(410, 110, 80, 80);
+
+ // No blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 210, 80, 80);
+
+ // Single float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple'});
+ ctx.fillRect(110, 210, 80, 80);
+
+ // Single negative float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5,
+ floodColor: 'purple'});
+ ctx.fillRect(210, 210, 80, 80);
+
+ // Two floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5],
+ floodColor: 'purple'});
+ ctx.fillRect(310, 210, 80, 80);
+
+ // Two negative floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5],
+ floodColor: 'purple'});
+ ctx.fillRect(410, 210, 80, 80);
+
+ // Degenerate parameter values.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null,
+ floodColor: 'purple', floodOpacity: [2]});
+ ctx.fillRect(10, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']],
+ floodColor: 'purple', floodOpacity: '0.8'});
+ ctx.fillRect(110, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false,
+ floodColor: 'purple', floodOpacity: ['0.4']});
+ ctx.fillRect(210, 310, 80, 80);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html
new file mode 100644
index 0000000000..fe9087244a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.filter.canvasFilterObject.dropShadow.tentative-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.dropShadow.tentative</title>
+<h1>2d.filter.canvasFilterObject.dropShadow.tentative</h1>
+<p class="desc">Test CanvasFilter() dropShadow object.</p>
+<canvas id="canvas" width="520" height="420">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(520, 420);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(0, 0, 520, 50);
+ ctx.fillRect(0, 100, 520, 50);
+ ctx.fillRect(0, 200, 520, 50);
+ ctx.fillRect(0, 300, 520, 50);
+
+ ctx.fillStyle = 'crimson';
+
+ // Parameter defaults.
+ ctx.filter = new CanvasFilter({name: 'dropShadow'});
+ ctx.fillRect(10, 10, 80, 80);
+
+ // All parameters specified.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple', floodOpacity: 0.7});
+ ctx.fillRect(110, 10, 80, 80);
+
+ // Named color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 110, 80, 80);
+
+ // System color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'LinkText'});
+ ctx.fillRect(110, 110, 80, 80);
+
+ // Numerical color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 1)'});
+ ctx.fillRect(210, 110, 80, 80);
+
+ // Transparent floodColor.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)'});
+ ctx.fillRect(310, 110, 80, 80);
+
+ // Transparent floodColor and floodOpacity.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7});
+ ctx.fillRect(410, 110, 80, 80);
+
+ // No blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 210, 80, 80);
+
+ // Single float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple'});
+ ctx.fillRect(110, 210, 80, 80);
+
+ // Single negative float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5,
+ floodColor: 'purple'});
+ ctx.fillRect(210, 210, 80, 80);
+
+ // Two floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5],
+ floodColor: 'purple'});
+ ctx.fillRect(310, 210, 80, 80);
+
+ // Two negative floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5],
+ floodColor: 'purple'});
+ ctx.fillRect(410, 210, 80, 80);
+
+ // Degenerate parameter values.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null,
+ floodColor: 'purple', floodOpacity: [2]});
+ ctx.fillRect(10, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']],
+ floodColor: 'purple', floodOpacity: '0.8'});
+ ctx.fillRect(110, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false,
+ floodColor: 'purple', floodOpacity: ['0.4']});
+ ctx.fillRect(210, 310, 80, 80);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html
new file mode 100644
index 0000000000..f9571f208e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="4 4" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html
new file mode 100644
index 0000000000..4417a1917c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.w.html
new file mode 100644
index 0000000000..d2024ad205
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html
new file mode 100644
index 0000000000..e76613271f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="4 1" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html
new file mode 100644
index 0000000000..2ea26359fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 1],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.w.html
new file mode 100644
index 0000000000..fa49ea4682
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 1],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html
new file mode 100644
index 0000000000..0f214fca9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="1 4" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html
new file mode 100644
index 0000000000..a9783ccb6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [1, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.w.html
new file mode 100644
index 0000000000..ab83f50ea0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [1, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html
new file mode 100644
index 0000000000..285a641726
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="4 0" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html
new file mode 100644
index 0000000000..3028c2a700
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 0],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.w.html
new file mode 100644
index 0000000000..e8482cf3ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [4, 0],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html
new file mode 100644
index 0000000000..d59945b5da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="100" height="100"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="0 4" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html
new file mode 100644
index 0000000000..fca324716b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [0, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.w.html
new file mode 100644
index 0000000000..50cfb3083a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html">
+<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title>
+<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1>
+<p class="desc">Test CanvasFilter() with gaussianBlur.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [0, 4],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.html
new file mode 100644
index 0000000000..fb99ef7d1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.tentative</h1>
+<p class="desc">Test CanvasFilter() object</p>
+
+
+<script>
+var t = async_test("Test CanvasFilter() object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1, 2]});
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = new CanvasFilter([
+ {name: 'gaussianBlur', stdDeviation: 5},
+ {name: 'gaussianBlur', stdDeviation: 10}
+ ]);
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.filter = ctx.filter;
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'none';
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ ctx.filter = 'this string is not a filter and should do nothing';
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.worker.js
new file mode 100644
index 0000000000..db95e0b006
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.worker.js
@@ -0,0 +1,44 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.tentative
+// Description:Test CanvasFilter() object
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test CanvasFilter() object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1, 2]});
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = new CanvasFilter([
+ {name: 'gaussianBlur', stdDeviation: 5},
+ {name: 'gaussianBlur', stdDeviation: 10}
+ ]);
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.filter = ctx.filter;
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'none';
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ ctx.filter = 'this string is not a filter and should do nothing';
+ _assert(ctx.filter.toString() == '[object CanvasFilter]', "ctx.filter.toString() == '[object CanvasFilter]'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html
new file mode 100644
index 0000000000..040c62a96b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.turbulence.inputTypes.tentative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.canvasFilterObject.turbulence.inputTypes.tentative</h1>
+<p class="desc">Test exceptions on CanvasFilter() turbulence object</p>
+
+
+<script>
+var t = async_test("Test exceptions on CanvasFilter() turbulence object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const errorTestCases = [
+ {baseFrequency: {}},
+ {baseFrequency: -1},
+ {baseFrequency: [0, -1]},
+ {baseFrequency: NaN},
+ {baseFrequency: Infinity},
+ {baseFrequency: undefined},
+ {baseFrequency: -Infinity},
+ {baseFrequency: 'test'},
+
+ {numOctaves: {}},
+ {numOctaves: -1},
+ {numOctaves: NaN},
+ {numOctaves: Infinity},
+ {numOctaves: undefined},
+ {numOctaves: -Infinity},
+ {numOctaves: [1, 1]},
+ {numOctaves: 'test'},
+
+ {seed: {}},
+ {seed: NaN},
+ {seed: Infinity},
+ {seed: undefined},
+ {seed: -Infinity},
+ {seed: [1, 1]},
+ {seed: 'test'},
+
+ {stitchTiles: {}},
+ {stitchTiles: NaN},
+ {stitchTiles: Infinity},
+ {stitchTiles: undefined},
+ {stitchTiles: -Infinity},
+ {stitchTiles: [1, 1]},
+ {stitchTiles: 'test'},
+ {stitchTiles: null},
+ {stitchTiles: []},
+ {stitchTiles: [10]},
+ {stitchTiles: 30},
+ {stitchTiles: false},
+ {stitchTiles: true},
+ {stitchTiles: '10'},
+ {stitchTiles: -1},
+
+ {type: {}},
+ {type: NaN},
+ {type: Infinity},
+ {type: undefined},
+ {type: -Infinity},
+ {type: [1, 1]},
+ {type: 'test'},
+ {type: null},
+ {type: []},
+ {type: [10]},
+ {type: 30},
+ {type: false},
+ {type: true},
+ {type: '10'},
+ {type: -1},
+ ]
+
+ // null and [] = 0 when parsed as number
+ const workingTestCases = [
+ {baseFrequency: null},
+ {baseFrequency: []},
+ {baseFrequency: [10]},
+ {baseFrequency: [10, 3]},
+ {baseFrequency: 30},
+ {baseFrequency: false},
+ {baseFrequency: true},
+ {baseFrequency: '10'},
+
+ {numOctaves: null},
+ {numOctaves: []},
+ {numOctaves: [10]},
+ {numOctaves: 30},
+ {numOctaves: false},
+ {numOctaves: true},
+ {numOctaves: '10'},
+
+ {seed: null},
+ {seed: []},
+ {seed: [10]},
+ {seed: 30},
+ {seed: false},
+ {seed: true},
+ {seed: '10'},
+ {seed: -1},
+
+ {stitchTiles: 'stitch'},
+ {stitchTiles: 'noStitch'},
+
+ {type: 'fractalNoise'},
+ {type: 'turbulence'},
+ ]
+
+ for (testCase of errorTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ assert_throws_js(TypeError, function() { new CanvasFilter(filterOptions); });
+ }
+
+ for (testCase of workingTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ _assert(new CanvasFilter(filterOptions) != null, "new CanvasFilter(filterOptions) != null");
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js
new file mode 100644
index 0000000000..1a950a9207
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js
@@ -0,0 +1,125 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.turbulence.inputTypes.tentative
+// Description:Test exceptions on CanvasFilter() turbulence object
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test exceptions on CanvasFilter() turbulence object");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const errorTestCases = [
+ {baseFrequency: {}},
+ {baseFrequency: -1},
+ {baseFrequency: [0, -1]},
+ {baseFrequency: NaN},
+ {baseFrequency: Infinity},
+ {baseFrequency: undefined},
+ {baseFrequency: -Infinity},
+ {baseFrequency: 'test'},
+
+ {numOctaves: {}},
+ {numOctaves: -1},
+ {numOctaves: NaN},
+ {numOctaves: Infinity},
+ {numOctaves: undefined},
+ {numOctaves: -Infinity},
+ {numOctaves: [1, 1]},
+ {numOctaves: 'test'},
+
+ {seed: {}},
+ {seed: NaN},
+ {seed: Infinity},
+ {seed: undefined},
+ {seed: -Infinity},
+ {seed: [1, 1]},
+ {seed: 'test'},
+
+ {stitchTiles: {}},
+ {stitchTiles: NaN},
+ {stitchTiles: Infinity},
+ {stitchTiles: undefined},
+ {stitchTiles: -Infinity},
+ {stitchTiles: [1, 1]},
+ {stitchTiles: 'test'},
+ {stitchTiles: null},
+ {stitchTiles: []},
+ {stitchTiles: [10]},
+ {stitchTiles: 30},
+ {stitchTiles: false},
+ {stitchTiles: true},
+ {stitchTiles: '10'},
+ {stitchTiles: -1},
+
+ {type: {}},
+ {type: NaN},
+ {type: Infinity},
+ {type: undefined},
+ {type: -Infinity},
+ {type: [1, 1]},
+ {type: 'test'},
+ {type: null},
+ {type: []},
+ {type: [10]},
+ {type: 30},
+ {type: false},
+ {type: true},
+ {type: '10'},
+ {type: -1},
+ ]
+
+ // null and [] = 0 when parsed as number
+ const workingTestCases = [
+ {baseFrequency: null},
+ {baseFrequency: []},
+ {baseFrequency: [10]},
+ {baseFrequency: [10, 3]},
+ {baseFrequency: 30},
+ {baseFrequency: false},
+ {baseFrequency: true},
+ {baseFrequency: '10'},
+
+ {numOctaves: null},
+ {numOctaves: []},
+ {numOctaves: [10]},
+ {numOctaves: 30},
+ {numOctaves: false},
+ {numOctaves: true},
+ {numOctaves: '10'},
+
+ {seed: null},
+ {seed: []},
+ {seed: [10]},
+ {seed: 30},
+ {seed: false},
+ {seed: true},
+ {seed: '10'},
+ {seed: -1},
+
+ {stitchTiles: 'stitch'},
+ {stitchTiles: 'noStitch'},
+
+ {type: 'fractalNoise'},
+ {type: 'turbulence'},
+ ]
+
+ for (testCase of errorTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ assert_throws_js(TypeError, function() { new CanvasFilter(filterOptions); });
+ }
+
+ for (testCase of workingTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ _assert(new CanvasFilter(filterOptions) != null, "new CanvasFilter(filterOptions) != null");
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.html
new file mode 100644
index 0000000000..5594174cf6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.filter.value</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.filter.value</h1>
+<p class="desc">test if ctx.filter works correctly</p>
+
+
+<script>
+var t = async_test("test if ctx.filter works correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.save();
+ ctx.filter = 'none';
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.restore();
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'blur(10)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'blur 10px';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'inherit';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'initial';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'unset';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = '';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = null;
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = undefined;
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'blur( 5px)';
+ assert_equals(ctx.filter, 'blur( 5px)');
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.worker.js
new file mode 100644
index 0000000000..2308315b63
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.value.worker.js
@@ -0,0 +1,51 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.filter.value
+// Description:test if ctx.filter works correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("test if ctx.filter works correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.filter = 'blur(5px)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.save();
+ ctx.filter = 'none';
+ _assert(ctx.filter == 'none', "ctx.filter == 'none'");
+ ctx.restore();
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'blur(10)';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'blur 10px';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'inherit';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'initial';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = 'unset';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = '';
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = null;
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+ ctx.filter = undefined;
+ _assert(ctx.filter == 'blur(5px)', "ctx.filter == 'blur(5px)'");
+
+ ctx.filter = 'blur( 5px)';
+ assert_equals(ctx.filter, 'blur( 5px)');
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic-expected.html
new file mode 100644
index 0000000000..6a6f0f6892
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.isotropic</title>
+<h1>2d.layer.anisotropic-blur.isotropic</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="4 4" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.html
new file mode 100644
index 0000000000..d59a4ccf62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.isotropic-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.isotropic</title>
+<h1>2d.layer.anisotropic-blur.isotropic</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.w.html
new file mode 100644
index 0000000000..15961d5c7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.isotropic.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.anisotropic-blur.isotropic-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.isotropic</title>
+<h1>2d.layer.anisotropic-blur.isotropic</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x-expected.html
new file mode 100644
index 0000000000..b0473f2ff0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-x</title>
+<h1>2d.layer.anisotropic-blur.mostly-x</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="4 1" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.html
new file mode 100644
index 0000000000..c5ad2ee6c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.mostly-x-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-x</title>
+<h1>2d.layer.anisotropic-blur.mostly-x</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 1] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.w.html
new file mode 100644
index 0000000000..60f5ac3ebd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-x.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.anisotropic-blur.mostly-x-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-x</title>
+<h1>2d.layer.anisotropic-blur.mostly-x</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 1] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y-expected.html
new file mode 100644
index 0000000000..43da016eea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-y</title>
+<h1>2d.layer.anisotropic-blur.mostly-y</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="1 4" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.html
new file mode 100644
index 0000000000..9545257cfa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.mostly-y-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-y</title>
+<h1>2d.layer.anisotropic-blur.mostly-y</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [1, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.w.html
new file mode 100644
index 0000000000..d533ad3187
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.mostly-y.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.anisotropic-blur.mostly-y-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.mostly-y</title>
+<h1>2d.layer.anisotropic-blur.mostly-y</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [1, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only-expected.html
new file mode 100644
index 0000000000..0b4d269189
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.x-only</title>
+<h1>2d.layer.anisotropic-blur.x-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="4 0" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.html
new file mode 100644
index 0000000000..4552ad4433
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.x-only-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.x-only</title>
+<h1>2d.layer.anisotropic-blur.x-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 0] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.w.html
new file mode 100644
index 0000000000..38abb21cd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.x-only.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.anisotropic-blur.x-only-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.x-only</title>
+<h1>2d.layer.anisotropic-blur.x-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [4, 0] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only-expected.html
new file mode 100644
index 0000000000..2572386412
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.anisotropic-blur.y-only</title>
+<h1>2d.layer.anisotropic-blur.y-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="0 4" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.html
new file mode 100644
index 0000000000..87dbcd3708
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.anisotropic-blur.y-only-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.y-only</title>
+<h1>2d.layer.anisotropic-blur.y-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [0, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.w.html
new file mode 100644
index 0000000000..062328db75
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.anisotropic-blur.y-only.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.anisotropic-blur.y-only-expected.html">
+<title>Canvas test: 2d.layer.anisotropic-blur.y-only</title>
+<h1>2d.layer.anisotropic-blur.y-only</h1>
+<p class="desc">Checks that layers allow gaussian blur with separate X and Y components.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: { name: 'gaussianBlur', stdDeviation: [0, 4] }});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.html
new file mode 100644
index 0000000000..4fb042a1d8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.beginLayer-options</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.beginLayer-options</h1>
+<p class="desc">Checks beginLayer works for different option parameter values</p>
+
+
+<script>
+var t = async_test("Checks beginLayer works for different option parameter values");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer(); ctx.endLayer();
+ ctx.beginLayer(null); ctx.endLayer();
+ ctx.beginLayer(undefined); ctx.endLayer();
+ ctx.beginLayer([]); ctx.endLayer();
+ ctx.beginLayer({}); ctx.endLayer();
+
+ assert_throws_js(TypeError, function() { ctx.beginLayer(''); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(0); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(1); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(true); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(false); });
+
+ ctx.beginLayer({filter: null}); ctx.endLayer();
+ ctx.beginLayer({filter: undefined}); ctx.endLayer();
+ ctx.beginLayer({filter: []}); ctx.endLayer();
+ ctx.beginLayer({filter: {}}); ctx.endLayer();
+ ctx.beginLayer({filter: {name: "unknown"}}); ctx.endLayer();
+ ctx.beginLayer({filter: ''}); ctx.endLayer();
+
+ // These cases don't throw TypeError since they can be casted to a
+ // DOMString.
+ ctx.beginLayer({filter: 0}); ctx.endLayer();
+ ctx.beginLayer({filter: 1}); ctx.endLayer();
+ ctx.beginLayer({filter: true}); ctx.endLayer();
+ ctx.beginLayer({filter: false}); ctx.endLayer();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.worker.js
new file mode 100644
index 0000000000..cafbc83f3e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.beginLayer-options.worker.js
@@ -0,0 +1,46 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.beginLayer-options
+// Description:Checks beginLayer works for different option parameter values
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Checks beginLayer works for different option parameter values");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer(); ctx.endLayer();
+ ctx.beginLayer(null); ctx.endLayer();
+ ctx.beginLayer(undefined); ctx.endLayer();
+ ctx.beginLayer([]); ctx.endLayer();
+ ctx.beginLayer({}); ctx.endLayer();
+
+ assert_throws_js(TypeError, function() { ctx.beginLayer(''); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(0); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(1); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(true); });
+ assert_throws_js(TypeError, function() { ctx.beginLayer(false); });
+
+ ctx.beginLayer({filter: null}); ctx.endLayer();
+ ctx.beginLayer({filter: undefined}); ctx.endLayer();
+ ctx.beginLayer({filter: []}); ctx.endLayer();
+ ctx.beginLayer({filter: {}}); ctx.endLayer();
+ ctx.beginLayer({filter: {name: "unknown"}}); ctx.endLayer();
+ ctx.beginLayer({filter: ''}); ctx.endLayer();
+
+ // These cases don't throw TypeError since they can be casted to a
+ // DOMString.
+ ctx.beginLayer({filter: 0}); ctx.endLayer();
+ ctx.beginLayer({filter: 1}); ctx.endLayer();
+ ctx.beginLayer({filter: true}); ctx.endLayer();
+ ctx.beginLayer({filter: false}); ctx.endLayer();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html
new file mode 100644
index 0000000000..6cad180f14
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping-expected.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.no-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.no-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur in="SourceGraphic" stdDeviation="30" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="201" y="50" width="100" height="100" fill="turquoise"/>
+ <rect x="50" y="201" width="100" height="100" fill="indigo"/>
+ <rect x="-101" y="50" width="100" height="100" fill="orange"/>
+ <rect x="50" y="-101" width="100" height="100" fill="brown"/>
+ </g>
+ </svg>`;
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ // No clipping.
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.html
new file mode 100644
index 0000000000..3cd1c674a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.blur-from-outside-canvas.no-clipping-expected.html">
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.no-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.no-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [ {name: 'gaussianBlur', stdDeviation: 30} ]});
+
+ ctx.fillStyle = 'turquoise';
+ ctx.fillRect(201, 50, 100, 100);
+ ctx.fillStyle = 'indigo';
+ ctx.fillRect(50, 201, 100, 100);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(-1, 50, -100, 100);
+ ctx.fillStyle = 'brown';
+ ctx.fillRect(50, -1, 100, -100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.w.html
new file mode 100644
index 0000000000..90b013c077
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.no-clipping.w.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.blur-from-outside-canvas.no-clipping-expected.html">
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.no-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.no-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [ {name: 'gaussianBlur', stdDeviation: 30} ]});
+
+ ctx.fillStyle = 'turquoise';
+ ctx.fillRect(201, 50, 100, 100);
+ ctx.fillStyle = 'indigo';
+ ctx.fillRect(50, 201, 100, 100);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(-1, 50, -100, 100);
+ ctx.fillStyle = 'brown';
+ ctx.fillRect(50, -1, 100, -100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html
new file mode 100644
index 0000000000..1823f78983
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping-expected.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.with-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.with-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur in="SourceGraphic" stdDeviation="30" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="201" y="50" width="100" height="100" fill="turquoise"/>
+ <rect x="50" y="201" width="100" height="100" fill="indigo"/>
+ <rect x="-101" y="50" width="100" height="100" fill="orange"/>
+ <rect x="50" y="-101" width="100" height="100" fill="brown"/>
+ </g>
+ </svg>`;
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.html
new file mode 100644
index 0000000000..76477445e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.blur-from-outside-canvas.with-clipping-expected.html">
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.with-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.with-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [ {name: 'gaussianBlur', stdDeviation: 30} ]});
+
+ ctx.fillStyle = 'turquoise';
+ ctx.fillRect(201, 50, 100, 100);
+ ctx.fillStyle = 'indigo';
+ ctx.fillRect(50, 201, 100, 100);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(-1, 50, -100, 100);
+ ctx.fillStyle = 'brown';
+ ctx.fillRect(50, -1, 100, -100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.w.html
new file mode 100644
index 0000000000..cf5570c932
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.blur-from-outside-canvas.with-clipping.w.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.blur-from-outside-canvas.with-clipping-expected.html">
+<title>Canvas test: 2d.layer.blur-from-outside-canvas.with-clipping</title>
+<h1>2d.layer.blur-from-outside-canvas.with-clipping</h1>
+<p class="desc">Checks blur leaking inside from drawing outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [ {name: 'gaussianBlur', stdDeviation: 30} ]});
+
+ ctx.fillStyle = 'turquoise';
+ ctx.fillRect(201, 50, 100, 100);
+ ctx.fillStyle = 'indigo';
+ ctx.fillRect(50, 201, 100, 100);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(-1, 50, -100, 100);
+ ctx.fillStyle = 'brown';
+ ctx.fillRect(50, -1, 100, -100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full-expected.html
new file mode 100644
index 0000000000..5a47f8e118
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clearRect.full</title>
+<h1>2d.layer.clearRect.full</h1>
+<p class="desc">clearRect inside a layer can clear all of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.html
new file mode 100644
index 0000000000..ec9f453b69
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clearRect.full-expected.html">
+<title>Canvas test: 2d.layer.clearRect.full</title>
+<h1>2d.layer.clearRect.full</h1>
+<p class="desc">clearRect inside a layer can clear all of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.fillStyle = 'green';
+ ctx.clearRect(0, 0, 100, 100);
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.w.html
new file mode 100644
index 0000000000..a6f4021dd5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.full.w.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.clearRect.full-expected.html">
+<title>Canvas test: 2d.layer.clearRect.full</title>
+<h1>2d.layer.clearRect.full</h1>
+<p class="desc">clearRect inside a layer can clear all of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.fillStyle = 'green';
+ ctx.clearRect(0, 0, 100, 100);
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial-expected.html
new file mode 100644
index 0000000000..ac75105cec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clearRect.partial</title>
+<h1>2d.layer.clearRect.partial</h1>
+<p class="desc">clearRect inside a layer can clear a portion of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 10);
+ ctx.fillRect(20, 60, 80, 10);
+ ctx.fillRect(20, 20, 10, 50);
+ ctx.fillRect(90, 20, 10, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.html
new file mode 100644
index 0000000000..88509a8a40
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clearRect.partial-expected.html">
+<title>Canvas test: 2d.layer.clearRect.partial</title>
+<h1>2d.layer.clearRect.partial</h1>
+<p class="desc">clearRect inside a layer can clear a portion of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.clearRect(30, 30, 60, 30);
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.w.html
new file mode 100644
index 0000000000..c6ba41afd7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clearRect.partial.w.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.clearRect.partial-expected.html">
+<title>Canvas test: 2d.layer.clearRect.partial</title>
+<h1>2d.layer.clearRect.partial</h1>
+<p class="desc">clearRect inside a layer can clear a portion of the layer content.</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.clearRect(30, 30, 60, 30);
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside-expected.html
new file mode 100644
index 0000000000..14e6d56245
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clip-inside-and-outside</title>
+<h1>2d.layer.clip-inside-and-outside</h1>
+<p class="desc">Check clipping set inside and outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginPath();
+ ctx2.rect(15, 15, 70, 70);
+ ctx2.clip();
+
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+
+ const canvas3 = new OffscreenCanvas(200, 200);
+ const ctx3 = canvas3.getContext('2d');
+
+ ctx3.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx3.drawImage(canvas2, 0, 0);
+ ctx3.endLayer();
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+ ctx.drawImage(canvas3, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.html
new file mode 100644
index 0000000000..03a3aee605
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clip-inside-and-outside-expected.html">
+<title>Canvas test: 2d.layer.clip-inside-and-outside</title>
+<h1>2d.layer.clip-inside-and-outside</h1>
+<p class="desc">Check clipping set inside and outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.w.html
new file mode 100644
index 0000000000..71f9fe7db4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.w.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.clip-inside-and-outside-expected.html">
+<title>Canvas test: 2d.layer.clip-inside-and-outside</title>
+<h1>2d.layer.clip-inside-and-outside</h1>
+<p class="desc">Check clipping set inside and outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-expected.html
new file mode 100644
index 0000000000..281fc1d913
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside-expected.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clip-inside</title>
+<h1>2d.layer.clip-inside</h1>
+<p class="desc">Check clipping set inside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginPath();
+ ctx2.rect(15, 15, 70, 70);
+ ctx2.clip();
+
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx.drawImage(canvas2, 0, 0);
+ ctx.endLayer();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.html
new file mode 100644
index 0000000000..e0c41f21e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clip-inside-expected.html">
+<title>Canvas test: 2d.layer.clip-inside</title>
+<h1>2d.layer.clip-inside</h1>
+<p class="desc">Check clipping set inside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.w.html
new file mode 100644
index 0000000000..9c4260a8ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-inside.w.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.clip-inside-expected.html">
+<title>Canvas test: 2d.layer.clip-inside</title>
+<h1>2d.layer.clip-inside</h1>
+<p class="desc">Check clipping set inside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside-expected.html
new file mode 100644
index 0000000000..1b18c2e8a7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside-expected.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.clip-outside</title>
+<h1>2d.layer.clip-outside</h1>
+<p class="desc">Check clipping set outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+ ctx2.endLayer();
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.html
new file mode 100644
index 0000000000..d2d091e96b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.clip-outside-expected.html">
+<title>Canvas test: 2d.layer.clip-outside</title>
+<h1>2d.layer.clip-outside</h1>
+<p class="desc">Check clipping set outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.w.html
new file mode 100644
index 0000000000..aed72db5ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.clip-outside.w.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.clip-outside-expected.html">
+<title>Canvas test: 2d.layer.clip-outside</title>
+<h1>2d.layer.clip-outside</h1>
+<p class="desc">Check clipping set outside the layer</p>
+<canvas id="canvas" width="100" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths-expected.html
new file mode 100644
index 0000000000..c394ecdfe3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.cross-layer-paths</title>
+<h1>2d.layer.cross-layer-paths</h1>
+<p class="desc">Checks that path defined in a layer is usable outside.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.moveTo(50, 0); ctx.lineTo(50, 100); ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.html
new file mode 100644
index 0000000000..f167ae00bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.cross-layer-paths-expected.html">
+<title>Canvas test: 2d.layer.cross-layer-paths</title>
+<h1>2d.layer.cross-layer-paths</h1>
+<p class="desc">Checks that path defined in a layer is usable outside.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ ctx.translate(50, 0);
+ ctx.moveTo(0, 0);
+ ctx.endLayer();
+ ctx.lineTo(50, 100);
+ ctx.stroke();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.w.html
new file mode 100644
index 0000000000..5b1f7f949c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.cross-layer-paths-expected.html">
+<title>Canvas test: 2d.layer.cross-layer-paths</title>
+<h1>2d.layer.cross-layer-paths</h1>
+<p class="desc">Checks that path defined in a layer is usable outside.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ ctx.translate(50, 0);
+ ctx.moveTo(0, 0);
+ ctx.endLayer();
+ ctx.lineTo(50, 100);
+ ctx.stroke();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow-expected.html
new file mode 100644
index 0000000000..85503ae33a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow-expected.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.css-filters.blur-and-shadow</title>
+<h1>2d.layer.css-filters.blur-and-shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="5" />
+ <feDropShadow dx="10" dy="10" stdDeviation="5" flood-color="orange" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.html
new file mode 100644
index 0000000000..a44ce4707f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.css-filters.blur-and-shadow-expected.html">
+<title>Canvas test: 2d.layer.css-filters.blur-and-shadow</title>
+<h1>2d.layer.css-filters.blur-and-shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'blur(5px) drop-shadow(10px 10px 5px orange)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.w.html
new file mode 100644
index 0000000000..9413ca6674
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-and-shadow.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.css-filters.blur-and-shadow-expected.html">
+<title>Canvas test: 2d.layer.css-filters.blur-and-shadow</title>
+<h1>2d.layer.css-filters.blur-and-shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'blur(5px) drop-shadow(10px 10px 5px orange)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-expected.html
new file mode 100644
index 0000000000..c6131f6c1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.css-filters.blur</title>
+<h1>2d.layer.css-filters.blur</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur stdDeviation="10" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.html
new file mode 100644
index 0000000000..5407ec37ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.css-filters.blur-expected.html">
+<title>Canvas test: 2d.layer.css-filters.blur</title>
+<h1>2d.layer.css-filters.blur</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'blur(10px)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.w.html
new file mode 100644
index 0000000000..35af0e1bfb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.blur.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.css-filters.blur-expected.html">
+<title>Canvas test: 2d.layer.css-filters.blur</title>
+<h1>2d.layer.css-filters.blur</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'blur(10px)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow-expected.html
new file mode 100644
index 0000000000..60f78d8096
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow-expected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.css-filters.shadow</title>
+<h1>2d.layer.css-filters.shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+
+<svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx="-10" dy="-10" stdDeviation="5" flood-color="purple" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.html
new file mode 100644
index 0000000000..28d6e6e403
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.css-filters.shadow-expected.html">
+<title>Canvas test: 2d.layer.css-filters.shadow</title>
+<h1>2d.layer.css-filters.shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'drop-shadow(-10px -10px 5px purple)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.w.html
new file mode 100644
index 0000000000..98e9d2fbd4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.css-filters.shadow.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.css-filters.shadow-expected.html">
+<title>Canvas test: 2d.layer.css-filters.shadow</title>
+<h1>2d.layer.css-filters.shadow</h1>
+<p class="desc">Checks that beginLayer works with a CSS filter string as input.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: 'drop-shadow(-10px -10px 5px purple)'});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.html
new file mode 100644
index 0000000000..a047c539cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.exceptions-are-no-op</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.exceptions-are-no-op</h1>
+<p class="desc">Checks that the context state is left unchanged if beginLayer throws.</p>
+
+
+<script>
+var t = async_test("Checks that the context state is left unchanged if beginLayer throws.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Get `beginLayer` to throw while parsing the filter.
+ assert_throws_js(TypeError,
+ () => ctx.beginLayer({filter: {name: 'colorMatrix',
+ values: 'foo'}}));
+ // `beginLayer` shouldn't have opened the layer, so `endLayer` should throw.
+ assert_throws_dom("InvalidStateError", () => ctx.endLayer());
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.worker.js
new file mode 100644
index 0000000000..bd1e376084
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.exceptions-are-no-op.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.exceptions-are-no-op
+// Description:Checks that the context state is left unchanged if beginLayer throws.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Checks that the context state is left unchanged if beginLayer throws.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Get `beginLayer` to throw while parsing the filter.
+ assert_throws_js(TypeError,
+ () => ctx.beginLayer({filter: {name: 'colorMatrix',
+ values: 'foo'}}));
+ // `beginLayer` shouldn't have opened the layer, so `endLayer` should throw.
+ assert_throws_dom("InvalidStateError", () => ctx.endLayer());
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter-expected.html
new file mode 100644
index 0000000000..88057fc354
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter-expected.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-filter</title>
+<h1>2d.layer.global-filter</h1>
+<p class="desc">Tests that layers ignore the global context filter.</p>
+<canvas id="canvas" width="150" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(60, 10, 30, 30);
+ ctx.filter = 'blur(5px)'
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.fillRect(110, 10, 30, 30);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.html
new file mode 100644
index 0000000000..2388a06a96
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-filter-expected.html">
+<title>Canvas test: 2d.layer.global-filter</title>
+<h1>2d.layer.global-filter</h1>
+<p class="desc">Tests that layers ignore the global context filter.</p>
+<canvas id="canvas" width="150" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(150, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.filter = 'blur(5px)'
+
+ ctx.beginLayer();
+ ctx.fillRect(10, 10, 30, 30); // `ctx.filter` applied to draw call.
+ ctx.endLayer();
+
+ ctx.beginLayer();
+ ctx.filter = 'none';
+ ctx.fillRect(60, 10, 30, 30); // Should not be filted by the layer.
+ ctx.endLayer();
+
+ ctx.fillRect(110, 10, 30, 30); // `ctx.filter` is still set.
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.w.html
new file mode 100644
index 0000000000..4c8f92d18a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-filter.w.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-filter-expected.html">
+<title>Canvas test: 2d.layer.global-filter</title>
+<h1>2d.layer.global-filter</h1>
+<p class="desc">Tests that layers ignore the global context filter.</p>
+<canvas id="canvas" width="150" height="100">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(150, 100);
+ const ctx = canvas.getContext('2d');
+
+ ctx.filter = 'blur(5px)'
+
+ ctx.beginLayer();
+ ctx.fillRect(10, 10, 30, 30); // `ctx.filter` applied to draw call.
+ ctx.endLayer();
+
+ ctx.beginLayer();
+ ctx.filter = 'none';
+ ctx.fillRect(60, 10, 30, 30); // Should not be filted by the layer.
+ ctx.endLayer();
+
+ ctx.fillRect(110, 10, 30, 30); // `ctx.filter` is still set.
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha-expected.html
new file mode 100644
index 0000000000..0666e3098a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha</title>
+<h1>2d.layer.global-states.alpha</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending-expected.html
new file mode 100644
index 0000000000..8a45027588
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending-expected.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.blending</title>
+<h1>2d.layer.global-states.alpha.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.html
new file mode 100644
index 0000000000..71414b4b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.blending</title>
+<h1>2d.layer.global-states.alpha.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow-expected.html
new file mode 100644
index 0000000000..f7b633b35f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow-expected.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.html
new file mode 100644
index 0000000000..ed2d2d70af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.w.html
new file mode 100644
index 0000000000..1ff3ad8385
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.shadow.w.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.alpha.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.w.html
new file mode 100644
index 0000000000..618480c813
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.blending.w.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.alpha.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.blending</title>
+<h1>2d.layer.global-states.alpha.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite-expected.html
new file mode 100644
index 0000000000..951049e638
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite-expected.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.composite</title>
+<h1>2d.layer.global-states.alpha.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.html
new file mode 100644
index 0000000000..94fed5752d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.composite</title>
+<h1>2d.layer.global-states.alpha.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow-expected.html
new file mode 100644
index 0000000000..0ae93871f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow-expected.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.html
new file mode 100644
index 0000000000..eb579cdcce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.w.html
new file mode 100644
index 0000000000..60e36f4b97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.shadow.w.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.alpha.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.w.html
new file mode 100644
index 0000000000..d7d2b7a21e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.composite.w.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.alpha.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.composite</title>
+<h1>2d.layer.global-states.alpha.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.html
new file mode 100644
index 0000000000..63a264e681
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha</title>
+<h1>2d.layer.global-states.alpha</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow-expected.html
new file mode 100644
index 0000000000..6f764c5001
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.alpha.shadow</title>
+<h1>2d.layer.global-states.alpha.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.html
new file mode 100644
index 0000000000..65a66c977d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.alpha.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.shadow</title>
+<h1>2d.layer.global-states.alpha.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.w.html
new file mode 100644
index 0000000000..f404601e3d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.shadow.w.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.alpha.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha.shadow</title>
+<h1>2d.layer.global-states.alpha.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.w.html
new file mode 100644
index 0000000000..694f31e208
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.alpha.w.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.alpha-expected.html">
+<title>Canvas test: 2d.layer.global-states.alpha</title>
+<h1>2d.layer.global-states.alpha</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending-expected.html
new file mode 100644
index 0000000000..33fdf46a28
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.blending</title>
+<h1>2d.layer.global-states.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.html
new file mode 100644
index 0000000000..6a36bb4ba1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.blending</title>
+<h1>2d.layer.global-states.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow-expected.html
new file mode 100644
index 0000000000..6f969074f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.blending.shadow</title>
+<h1>2d.layer.global-states.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.html
new file mode 100644
index 0000000000..2e91f3d2d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.blending.shadow</title>
+<h1>2d.layer.global-states.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.w.html
new file mode 100644
index 0000000000..d8e20d0479
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.w.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.blending.shadow</title>
+<h1>2d.layer.global-states.blending.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.w.html
new file mode 100644
index 0000000000..8964e97713
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.blending.w.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.blending</title>
+<h1>2d.layer.global-states.blending</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite-expected.html
new file mode 100644
index 0000000000..ed7669c4cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.composite</title>
+<h1>2d.layer.global-states.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.html
new file mode 100644
index 0000000000..84fb4b3d95
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.composite</title>
+<h1>2d.layer.global-states.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow-expected.html
new file mode 100644
index 0000000000..b687c27f47
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.composite.shadow</title>
+<h1>2d.layer.global-states.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.html
new file mode 100644
index 0000000000..1e3ab4d6a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.composite.shadow</title>
+<h1>2d.layer.global-states.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.w.html
new file mode 100644
index 0000000000..7dfb70148b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.shadow.w.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.composite.shadow</title>
+<h1>2d.layer.global-states.composite.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.w.html
new file mode 100644
index 0000000000..b695871fcd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.composite.w.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.composite</title>
+<h1>2d.layer.global-states.composite</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha-expected.html
new file mode 100644
index 0000000000..f304700feb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha</title>
+<h1>2d.layer.global-states.filter.alpha</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending-expected.html
new file mode 100644
index 0000000000..7c91ce4229
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending-expected.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title>
+<h1>2d.layer.global-states.filter.alpha.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html
new file mode 100644
index 0000000000..be6f962b33
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title>
+<h1>2d.layer.global-states.filter.alpha.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html
new file mode 100644
index 0000000000..62942ffeae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow-expected.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.html
new file mode 100644
index 0000000000..62d98d967c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.w.html
new file mode 100644
index 0000000000..e81efd6b8d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.shadow.w.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.alpha.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html
new file mode 100644
index 0000000000..2b53ad7c1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.alpha.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title>
+<h1>2d.layer.global-states.filter.alpha.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite-expected.html
new file mode 100644
index 0000000000..8e0d98648e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite-expected.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title>
+<h1>2d.layer.global-states.filter.alpha.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html
new file mode 100644
index 0000000000..087fea88af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title>
+<h1>2d.layer.global-states.filter.alpha.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html
new file mode 100644
index 0000000000..a649972546
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow-expected.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.html
new file mode 100644
index 0000000000..d067ff2f5e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.w.html
new file mode 100644
index 0000000000..39abc78b17
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.shadow.w.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.alpha.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html
new file mode 100644
index 0000000000..6aa83a3278
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.alpha.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title>
+<h1>2d.layer.global-states.filter.alpha.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html
new file mode 100644
index 0000000000..f1d631c25c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha</title>
+<h1>2d.layer.global-states.filter.alpha</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow-expected.html
new file mode 100644
index 0000000000..169baee29b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow-expected.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html
new file mode 100644
index 0000000000..2548c21181
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.alpha.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html
new file mode 100644
index 0000000000..5e1494422e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.alpha.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title>
+<h1>2d.layer.global-states.filter.alpha.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html
new file mode 100644
index 0000000000..e75d668ad5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.alpha-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.alpha</title>
+<h1>2d.layer.global-states.filter.alpha</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalAlpha = 0.6;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending-expected.html
new file mode 100644
index 0000000000..f81dcf72dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.blending</title>
+<h1>2d.layer.global-states.filter.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.html
new file mode 100644
index 0000000000..ce2b046798
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.blending</title>
+<h1>2d.layer.global-states.filter.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow-expected.html
new file mode 100644
index 0000000000..91f3725f8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow-expected.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.blending.shadow</title>
+<h1>2d.layer.global-states.filter.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.html
new file mode 100644
index 0000000000..d0d429bee3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.blending.shadow</title>
+<h1>2d.layer.global-states.filter.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.w.html
new file mode 100644
index 0000000000..ce432ea74d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.w.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.blending.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.blending.shadow</title>
+<h1>2d.layer.global-states.filter.blending.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.w.html
new file mode 100644
index 0000000000..bb101cdc0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.w.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.blending-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.blending</title>
+<h1>2d.layer.global-states.filter.blending</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'multiply';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite-expected.html
new file mode 100644
index 0000000000..97e85a1593
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.composite</title>
+<h1>2d.layer.global-states.filter.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.html
new file mode 100644
index 0000000000..32052a1150
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.composite</title>
+<h1>2d.layer.global-states.filter.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow-expected.html
new file mode 100644
index 0000000000..4716bb2760
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow-expected.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.composite.shadow</title>
+<h1>2d.layer.global-states.filter.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.html
new file mode 100644
index 0000000000..b5e8b9f843
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.composite.shadow</title>
+<h1>2d.layer.global-states.filter.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.w.html
new file mode 100644
index 0000000000..894089d88e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.shadow.w.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.composite.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.composite.shadow</title>
+<h1>2d.layer.global-states.filter.composite.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.w.html
new file mode 100644
index 0000000000..41ccdaf5c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.composite.w.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.composite-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.composite</title>
+<h1>2d.layer.global-states.filter.composite</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states-expected.html
new file mode 100644
index 0000000000..e56fe0b360
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states-expected.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.no-global-states</title>
+<h1>2d.layer.global-states.filter.no-global-states</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.html
new file mode 100644
index 0000000000..3effa3ee9d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.no-global-states-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.no-global-states</title>
+<h1>2d.layer.global-states.filter.no-global-states</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.w.html
new file mode 100644
index 0000000000..ec744d7ffe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-global-states.w.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.no-global-states-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.no-global-states</title>
+<h1>2d.layer.global-states.filter.no-global-states</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow-expected.html
new file mode 100644
index 0000000000..13ba2dd4cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow-expected.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.filter.shadow</title>
+<h1>2d.layer.global-states.filter.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="200" height="200"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = 200;
+ img.height = 200;
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.html
new file mode 100644
index 0000000000..7bb0ef5e13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.filter.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.shadow</title>
+<h1>2d.layer.global-states.filter.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.w.html
new file mode 100644
index 0000000000..bc9bd48aad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.shadow.w.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.filter.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.filter.shadow</title>
+<h1>2d.layer.global-states.filter.shadow</h1>
+<p class="desc">Checks that layers with filters correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states-expected.html
new file mode 100644
index 0000000000..b91a2ae8b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states-expected.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.no-global-states</title>
+<h1>2d.layer.global-states.no-global-states</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.html
new file mode 100644
index 0000000000..c8a9815381
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.no-global-states-expected.html">
+<title>Canvas test: 2d.layer.global-states.no-global-states</title>
+<h1>2d.layer.global-states.no-global-states</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.w.html
new file mode 100644
index 0000000000..db03a3fd0c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.no-global-states.w.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.no-global-states-expected.html">
+<title>Canvas test: 2d.layer.global-states.no-global-states</title>
+<h1>2d.layer.global-states.no-global-states</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ // No global states.
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow-expected.html
new file mode 100644
index 0000000000..835e9d420a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.global-states.shadow</title>
+<h1>2d.layer.global-states.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.html
new file mode 100644
index 0000000000..ad60e87fb1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.global-states.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.shadow</title>
+<h1>2d.layer.global-states.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.w.html
new file mode 100644
index 0000000000..1fc35fd33a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.shadow.w.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.global-states.shadow-expected.html">
+<title>Canvas test: 2d.layer.global-states.shadow</title>
+<h1>2d.layer.global-states.shadow</h1>
+<p class="desc">Checks that layers correctly use global render states.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html
new file mode 100644
index 0000000000..c0b11aa611
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.invalid-calls.beginLayer-reset-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.invalid-calls.beginLayer-reset-endLayer</h1>
+<p class="desc">Raises exception on beginLayer() + reset() + endLayer().</p>
+
+
+<script>
+var t = async_test("Raises exception on beginLayer() + reset() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.reset();
+ ctx.endLayer();
+ });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.worker.js
new file mode 100644
index 0000000000..1c147d6f34
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-reset-endLayer.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.invalid-calls.beginLayer-reset-endLayer
+// Description:Raises exception on beginLayer() + reset() + endLayer().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Raises exception on beginLayer() + reset() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.reset();
+ ctx.endLayer();
+ });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.html
new file mode 100644
index 0000000000..022532b329
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.invalid-calls.beginLayer-restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.invalid-calls.beginLayer-restore</h1>
+<p class="desc">Raises exception on beginLayer() + restore().</p>
+
+
+<script>
+var t = async_test("Raises exception on beginLayer() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.restore();
+ });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.worker.js
new file mode 100644
index 0000000000..1aa86635e6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-restore.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.invalid-calls.beginLayer-restore
+// Description:Raises exception on beginLayer() + restore().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Raises exception on beginLayer() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.restore();
+ });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html
new file mode 100644
index 0000000000..26dd0eee4b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.invalid-calls.beginLayer-save-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.invalid-calls.beginLayer-save-endLayer</h1>
+<p class="desc">Raises exception on beginLayer() + save() + endLayer().</p>
+
+
+<script>
+var t = async_test("Raises exception on beginLayer() + save() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.save();
+ ctx.endLayer();
+ });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.worker.js
new file mode 100644
index 0000000000..613921c67c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.beginLayer-save-endLayer.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.invalid-calls.beginLayer-save-endLayer
+// Description:Raises exception on beginLayer() + save() + endLayer().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Raises exception on beginLayer() + save() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.beginLayer();
+ ctx.save();
+ ctx.endLayer();
+ });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.html
new file mode 100644
index 0000000000..440249980a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.invalid-calls.endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.invalid-calls.endLayer</h1>
+<p class="desc">Raises exception on lone endLayer calls.</p>
+
+
+<script>
+var t = async_test("Raises exception on lone endLayer calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.endLayer();
+ });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.worker.js
new file mode 100644
index 0000000000..b2ba231b9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.endLayer.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.invalid-calls.endLayer
+// Description:Raises exception on lone endLayer calls.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Raises exception on lone endLayer calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.endLayer();
+ });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.html
new file mode 100644
index 0000000000..c2b09961ac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.invalid-calls.save-beginLayer-restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.invalid-calls.save-beginLayer-restore</h1>
+<p class="desc">Raises exception on save() + beginLayer() + restore().</p>
+
+
+<script>
+var t = async_test("Raises exception on save() + beginLayer() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.save();
+ ctx.beginLayer();
+ ctx.restore();
+ });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.worker.js
new file mode 100644
index 0000000000..d155379fcb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-beginLayer-restore.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.invalid-calls.save-beginLayer-restore
+// Description:Raises exception on save() + beginLayer() + restore().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Raises exception on save() + beginLayer() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.save();
+ ctx.beginLayer();
+ ctx.restore();
+ });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.html
new file mode 100644
index 0000000000..01b62d1e85
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.invalid-calls.save-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.invalid-calls.save-endLayer</h1>
+<p class="desc">Raises exception on save() + endLayer().</p>
+
+
+<script>
+var t = async_test("Raises exception on save() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.save();
+ ctx.endLayer();
+ });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.worker.js
new file mode 100644
index 0000000000..353c1b00cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.invalid-calls.save-endLayer.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.invalid-calls.save-endLayer
+// Description:Raises exception on save() + endLayer().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Raises exception on save() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ ctx.save();
+ ctx.endLayer();
+ });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.html
new file mode 100644
index 0000000000..867553b45e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.layer-rendering-state-reset-in-layer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.layer-rendering-state-reset-in-layer</h1>
+<p class="desc">Tests that layers ignore the global context filter.</p>
+
+
+<script>
+var t = async_test("Tests that layers ignore the global context filter.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#0000ff';
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 20;
+ ctx.shadowBlur = 30;
+
+ _assertSame(ctx.globalAlpha, 0.5, "ctx.globalAlpha", "0.5");
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ _assertSame(ctx.shadowColor, '#0000ff', "ctx.shadowColor", "'#0000ff'");
+ _assertSame(ctx.shadowOffsetX, 10, "ctx.shadowOffsetX", "10");
+ _assertSame(ctx.shadowOffsetY, 20, "ctx.shadowOffsetY", "20");
+ _assertSame(ctx.shadowBlur, 30, "ctx.shadowBlur", "30");
+
+ ctx.beginLayer();
+
+ _assertSame(ctx.globalAlpha, 1.0, "ctx.globalAlpha", "1.0");
+ _assertSame(ctx.globalCompositeOperation, 'source-over', "ctx.globalCompositeOperation", "'source-over'");
+ _assertSame(ctx.shadowColor, 'rgba(0, 0, 0, 0)', "ctx.shadowColor", "'rgba(0, 0, 0, 0)'");
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+
+ ctx.endLayer();
+
+ _assertSame(ctx.globalAlpha, 0.5, "ctx.globalAlpha", "0.5");
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ _assertSame(ctx.shadowColor, '#0000ff', "ctx.shadowColor", "'#0000ff'");
+ _assertSame(ctx.shadowOffsetX, 10, "ctx.shadowOffsetX", "10");
+ _assertSame(ctx.shadowOffsetY, 20, "ctx.shadowOffsetY", "20");
+ _assertSame(ctx.shadowBlur, 30, "ctx.shadowBlur", "30");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.worker.js
new file mode 100644
index 0000000000..5c2bb73e8f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.layer-rendering-state-reset-in-layer.worker.js
@@ -0,0 +1,52 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.layer-rendering-state-reset-in-layer
+// Description:Tests that layers ignore the global context filter.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Tests that layers ignore the global context filter.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalAlpha = 0.5;
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#0000ff';
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 20;
+ ctx.shadowBlur = 30;
+
+ _assertSame(ctx.globalAlpha, 0.5, "ctx.globalAlpha", "0.5");
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ _assertSame(ctx.shadowColor, '#0000ff', "ctx.shadowColor", "'#0000ff'");
+ _assertSame(ctx.shadowOffsetX, 10, "ctx.shadowOffsetX", "10");
+ _assertSame(ctx.shadowOffsetY, 20, "ctx.shadowOffsetY", "20");
+ _assertSame(ctx.shadowBlur, 30, "ctx.shadowBlur", "30");
+
+ ctx.beginLayer();
+
+ _assertSame(ctx.globalAlpha, 1.0, "ctx.globalAlpha", "1.0");
+ _assertSame(ctx.globalCompositeOperation, 'source-over', "ctx.globalCompositeOperation", "'source-over'");
+ _assertSame(ctx.shadowColor, 'rgba(0, 0, 0, 0)', "ctx.shadowColor", "'rgba(0, 0, 0, 0)'");
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+
+ ctx.endLayer();
+
+ _assertSame(ctx.globalAlpha, 0.5, "ctx.globalAlpha", "0.5");
+ _assertSame(ctx.globalCompositeOperation, 'xor', "ctx.globalCompositeOperation", "'xor'");
+ _assertSame(ctx.shadowColor, '#0000ff', "ctx.shadowColor", "'#0000ff'");
+ _assertSame(ctx.shadowOffsetX, 10, "ctx.shadowOffsetX", "10");
+ _assertSame(ctx.shadowOffsetY, 20, "ctx.shadowOffsetY", "20");
+ _assertSame(ctx.shadowBlur, 30, "ctx.shadowBlur", "30");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.html
new file mode 100644
index 0000000000..0b3854c31d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.malformed-operations-with-promises.convertToBlob</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.malformed-operations-with-promises.convertToBlob</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ await canvas.convertToBlob();
+ // Make sure the exception isn't caused by calling the function twice.
+ await canvas.convertToBlob();
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ await promise_rejects_dom(t, 'InvalidStateError', canvas.convertToBlob());
+
+}, "Check that exceptions are thrown for operations that are malformed while layers are open.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.worker.js
new file mode 100644
index 0000000000..be0f4f2cde
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.convertToBlob.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.malformed-operations-with-promises.convertToBlob
+// Description:Check that exceptions are thrown for operations that are malformed while layers are open.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ await canvas.convertToBlob();
+ // Make sure the exception isn't caused by calling the function twice.
+ await canvas.convertToBlob();
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ await promise_rejects_dom(t, 'InvalidStateError', canvas.convertToBlob());
+ t.done();
+}, "Check that exceptions are thrown for operations that are malformed while layers are open.");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html
new file mode 100644
index 0000000000..085554d9f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.malformed-operations-with-promises.createImageBitmap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.malformed-operations-with-promises.createImageBitmap</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ await createImageBitmap(canvas);
+ // Make sure the exception isn't caused by calling the function twice.
+ await createImageBitmap(canvas);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ await promise_rejects_dom(t, 'InvalidStateError', createImageBitmap(canvas));
+
+}, "Check that exceptions are thrown for operations that are malformed while layers are open.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.worker.js
new file mode 100644
index 0000000000..b286b7a9e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations-with-promises.createImageBitmap.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.malformed-operations-with-promises.createImageBitmap
+// Description:Check that exceptions are thrown for operations that are malformed while layers are open.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ await createImageBitmap(canvas);
+ // Make sure the exception isn't caused by calling the function twice.
+ await createImageBitmap(canvas);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ await promise_rejects_dom(t, 'InvalidStateError', createImageBitmap(canvas));
+ t.done();
+}, "Check that exceptions are thrown for operations that are malformed while layers are open.");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.html
new file mode 100644
index 0000000000..a206e64ceb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.malformed-operations.createPattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.malformed-operations.createPattern</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ ctx.createPattern(canvas, 'repeat');
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.createPattern(canvas, 'repeat');
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.createPattern(canvas, 'repeat'));
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.worker.js
new file mode 100644
index 0000000000..bcb42cba87
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.createPattern.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.malformed-operations.createPattern
+// Description:Check that exceptions are thrown for operations that are malformed while layers are open.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ ctx.createPattern(canvas, 'repeat');
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.createPattern(canvas, 'repeat');
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.createPattern(canvas, 'repeat'));
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.html
new file mode 100644
index 0000000000..e6a9872100
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.malformed-operations.drawImage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.malformed-operations.drawImage</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+ // Shouldn't throw on its own.
+ ctx2.drawImage(canvas, 0, 0);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx2.drawImage(canvas, 0, 0);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx2.drawImage(canvas, 0, 0));
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.worker.js
new file mode 100644
index 0000000000..b66cdee62e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.drawImage.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.malformed-operations.drawImage
+// Description:Check that exceptions are thrown for operations that are malformed while layers are open.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+ // Shouldn't throw on its own.
+ ctx2.drawImage(canvas, 0, 0);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx2.drawImage(canvas, 0, 0);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx2.drawImage(canvas, 0, 0));
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.html
new file mode 100644
index 0000000000..87bc8c6ede
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.malformed-operations.getImageData</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.malformed-operations.getImageData</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ ctx.getImageData(0, 0, 200, 200);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.getImageData(0, 0, 200, 200);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.getImageData(0, 0, 200, 200));
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.worker.js
new file mode 100644
index 0000000000..6a1a16fccb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.getImageData.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.malformed-operations.getImageData
+// Description:Check that exceptions are thrown for operations that are malformed while layers are open.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ ctx.getImageData(0, 0, 200, 200);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.getImageData(0, 0, 200, 200);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.getImageData(0, 0, 200, 200));
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.html
new file mode 100644
index 0000000000..e8059076bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.malformed-operations.putImageData</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.malformed-operations.putImageData</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d')
+ const data = ctx2.getImageData(0, 0, 1, 1);
+ // Shouldn't throw on its own.
+ ctx.putImageData(data, 0, 0);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.putImageData(data, 0, 0);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.putImageData(data, 0, 0));
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.worker.js
new file mode 100644
index 0000000000..8810c3a73c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.putImageData.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.malformed-operations.putImageData
+// Description:Check that exceptions are thrown for operations that are malformed while layers are open.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d')
+ const data = ctx2.getImageData(0, 0, 1, 1);
+ // Shouldn't throw on its own.
+ ctx.putImageData(data, 0, 0);
+ // Make sure the exception isn't caused by calling the function twice.
+ ctx.putImageData(data, 0, 0);
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => ctx.putImageData(data, 0, 0));
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.html
new file mode 100644
index 0000000000..79c216421f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.malformed-operations.transferToImageBitmap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.malformed-operations.transferToImageBitmap</h1>
+<p class="desc">Check that exceptions are thrown for operations that are malformed while layers are open.</p>
+
+
+<script>
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ canvas.transferToImageBitmap();
+ // Make sure the exception isn't caused by calling the function twice.
+ canvas.transferToImageBitmap();
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => canvas.transferToImageBitmap());
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.worker.js
new file mode 100644
index 0000000000..be0b43665a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.malformed-operations.transferToImageBitmap.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.malformed-operations.transferToImageBitmap
+// Description:Check that exceptions are thrown for operations that are malformed while layers are open.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that exceptions are thrown for operations that are malformed while layers are open.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(200, 200);
+ var ctx = canvas.getContext('2d');
+
+ // Shouldn't throw on its own.
+ canvas.transferToImageBitmap();
+ // Make sure the exception isn't caused by calling the function twice.
+ canvas.transferToImageBitmap();
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => canvas.transferToImageBitmap());
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-expected.html
new file mode 100644
index 0000000000..65525d4d6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-expected.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.nested</title>
+<h1>2d.layer.nested</h1>
+<p class="desc">Tests nested canvas layers.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 40, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx2.fillRect(60, 60, 75, 50);
+
+ ctx2.globalAlpha = 0.5;
+
+ canvas3 = document.createElement("canvas");
+ ctx3 = canvas3.getContext("2d");
+
+ ctx3.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx3.fillRect(50, 50, 75, 50);
+ ctx3.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx3.fillRect(70, 70, 75, 50);
+
+ ctx2.drawImage(canvas3, 0, 0);
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters-expected.html
new file mode 100644
index 0000000000..8b53e2dc76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters-expected.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.nested-filters</title>
+<h1>2d.layer.nested-filters</h1>
+<p class="desc">Checks that nested layers work properly when both apply filters.</p>
+<canvas id="canvas" width="400" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(20, 20, 100, 100);
+ ctx.fillRect(30, 30, 100, 100);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(40, 40, 100, 100);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(280, 80, 100, 100);
+ ctx.fillRect(270, 70, 100, 100);
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(260, 60, 100, 100);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(250, 50, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.html
new file mode 100644
index 0000000000..adf99bacbe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.nested-filters-expected.html">
+<title>Canvas test: 2d.layer.nested-filters</title>
+<h1>2d.layer.nested-filters</h1>
+<p class="desc">Checks that nested layers work properly when both apply filters.</p>
+<canvas id="canvas" width="400" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(400, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -20, dy: -20,
+ stdDeviation: 0, floodColor: 'yellow'}});
+ ctx.beginLayer({filter: 'drop-shadow(-10px -10px 0 blue)'});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ ctx.beginLayer({filter: 'drop-shadow(20px 20px 0 blue)'});
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: 10, dy: 10,
+ stdDeviation: 0, floodColor: 'yellow'}});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(250, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.w.html
new file mode 100644
index 0000000000..0616fecfd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested-filters.w.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.nested-filters-expected.html">
+<title>Canvas test: 2d.layer.nested-filters</title>
+<h1>2d.layer.nested-filters</h1>
+<p class="desc">Checks that nested layers work properly when both apply filters.</p>
+<canvas id="canvas" width="400" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(400, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -20, dy: -20,
+ stdDeviation: 0, floodColor: 'yellow'}});
+ ctx.beginLayer({filter: 'drop-shadow(-10px -10px 0 blue)'});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ ctx.beginLayer({filter: 'drop-shadow(20px 20px 0 blue)'});
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: 10, dy: 10,
+ stdDeviation: 0, floodColor: 'yellow'}});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(250, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.html
new file mode 100644
index 0000000000..9e5b7d5826
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.nested-expected.html">
+<title>Canvas test: 2d.layer.nested</title>
+<h1>2d.layer.nested</h1>
+<p class="desc">Tests nested canvas layers.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 40, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.w.html
new file mode 100644
index 0000000000..99e7390609
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.nested.w.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.nested-expected.html">
+<title>Canvas test: 2d.layer.nested</title>
+<h1>2d.layer.nested</h1>
+<p class="desc">Tests nested canvas layers.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 40, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas-expected.html
new file mode 100644
index 0000000000..89c85de1e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas-expected.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.opaque-canvas</title>
+<h1>2d.layer.opaque-canvas</h1>
+<p class="desc">Checks that layer blending works inside opaque canvas</p>
+<canvas id="canvas" width="300" height="300">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 300, 300);
+
+ ctx.fillStyle = 'black';
+ ctx.fillRect(0, 0, 200, 200);
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(10, 10, 100, 100);
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = 'green';
+ ctx2.fillRect(50, 50, 100, 100);
+ ctx2.globalAlpha = 0.8;
+ ctx2.fillStyle = 'yellow';
+ ctx2.fillRect(75, 25, 100, 100);
+
+ ctx.shadowColor = 'rgba(200, 100, 50, 0.5)';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.drawImage(canvas2, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.html
new file mode 100644
index 0000000000..f9759abebe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.opaque-canvas-expected.html">
+<title>Canvas test: 2d.layer.opaque-canvas</title>
+<h1>2d.layer.opaque-canvas</h1>
+<p class="desc">Checks that layer blending works inside opaque canvas</p>
+<canvas id="canvas" width="300" height="300">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(300, 300);
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d', {alpha: false});
+
+ ctx2.fillStyle = 'purple';
+ ctx2.fillRect(10, 10, 100, 100);
+
+ ctx2.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: 10,
+ stdDeviation: 0,
+ floodColor: 'rgba(200, 100, 50, 0.5)'}});
+ ctx2.fillStyle = 'green';
+ ctx2.fillRect(50, 50, 100, 100);
+ ctx2.globalAlpha = 0.8;
+ ctx2.fillStyle = 'yellow';
+ ctx2.fillRect(75, 25, 100, 100);
+ ctx2.endLayer();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 300, 300);
+ ctx.drawImage(canvas2, 0, 0);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.w.html
new file mode 100644
index 0000000000..ff5ec19418
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.opaque-canvas.w.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.opaque-canvas-expected.html">
+<title>Canvas test: 2d.layer.opaque-canvas</title>
+<h1>2d.layer.opaque-canvas</h1>
+<p class="desc">Checks that layer blending works inside opaque canvas</p>
+<canvas id="canvas" width="300" height="300">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(300, 300);
+ const ctx = canvas.getContext('2d');
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d', {alpha: false});
+
+ ctx2.fillStyle = 'purple';
+ ctx2.fillRect(10, 10, 100, 100);
+
+ ctx2.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: 10,
+ stdDeviation: 0,
+ floodColor: 'rgba(200, 100, 50, 0.5)'}});
+ ctx2.fillStyle = 'green';
+ ctx2.fillRect(50, 50, 100, 100);
+ ctx2.globalAlpha = 0.8;
+ ctx2.fillStyle = 'yellow';
+ ctx2.fillRect(75, 25, 100, 100);
+ ctx2.endLayer();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 300, 300);
+ ctx.drawImage(canvas2, 0, 0);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset-expected.html
new file mode 100644
index 0000000000..93131dca9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.reset</title>
+<h1>2d.layer.reset</h1>
+<p class="desc">Checks that reset discards any pending layers.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(10, 10, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.html
new file mode 100644
index 0000000000..3254c0a048
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.reset-expected.html">
+<title>Canvas test: 2d.layer.reset</title>
+<h1>2d.layer.reset</h1>
+<p class="desc">Checks that reset discards any pending layers.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ // Global states:
+ ctx.globalAlpha = 0.3;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -3;
+ ctx.shadowOffsetY = 3;
+ ctx.shadowColor = 'rgba(0, 30, 0, 0.3)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -3, dy: 3}});
+
+ // Layer states:
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -6;
+ ctx.shadowOffsetY = 6;
+ ctx.shadowColor = 'rgba(0, 60, 0, 0.6)';
+ ctx.shadowBlur = 3;
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 75, 50);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.w.html
new file mode 100644
index 0000000000..09bd6451bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.reset.w.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.reset-expected.html">
+<title>Canvas test: 2d.layer.reset</title>
+<h1>2d.layer.reset</h1>
+<p class="desc">Checks that reset discards any pending layers.</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ // Global states:
+ ctx.globalAlpha = 0.3;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -3;
+ ctx.shadowOffsetY = 3;
+ ctx.shadowColor = 'rgba(0, 30, 0, 0.3)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -3, dy: 3}});
+
+ // Layer states:
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -6;
+ ctx.shadowOffsetY = 6;
+ ctx.shadowColor = 'rgba(0, 60, 0, 0.6)';
+ ctx.shadowBlur = 3;
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 75, 50);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style-expected.html
new file mode 100644
index 0000000000..1d0ac3558d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style-expected.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.restore-style</title>
+<h1>2d.layer.restore-style</h1>
+<p class="desc">Test that ensure layers restores style values upon endLayer.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(60, 60, 75, 50);
+ ctx.drawImage(canvas2, 0, 0);
+
+ ctx.fillRect(70, 70, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.html
new file mode 100644
index 0000000000..a3593cd2a8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.restore-style-expected.html">
+<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-950">
+<title>Canvas test: 2d.layer.restore-style</title>
+<h1>2d.layer.restore-style</h1>
+<p class="desc">Test that ensure layers restores style values upon endLayer.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0,0,255,1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(70, 70, 75, 50);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.w.html
new file mode 100644
index 0000000000..a66fc2bc59
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.restore-style.w.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.restore-style-expected.html">
+<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-950">
+<title>Canvas test: 2d.layer.restore-style</title>
+<h1>2d.layer.restore-style</h1>
+<p class="desc">Test that ensure layers restores style values upon endLayer.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0,0,255,1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(70, 70, 75, 50);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex-expected.html
new file mode 100644
index 0000000000..ef46f69e2a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex-expected.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.several-complex</title>
+<h1>2d.layer.several-complex</h1>
+<p class="desc">Test to ensure beginlayer works for filter, alpha and shadow, even with consecutive layers.</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 95, 70);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'orange';
+ ctx.shadowBlur = 3;
+
+ var canvas2 = [5];
+ var ctx2 = [5];
+
+ for (let i = 0; i < 5; i++) {
+ canvas2[i] = document.createElement("canvas");
+ ctx2[i] = canvas2[i].getContext("2d");
+ ctx2[i].fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2[i].fillRect(60, 40, 75, 50);
+ ctx2[i].fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2[i].fillRect(80, 60, 75, 50);
+
+ ctx.drawImage(canvas2[i], i, i);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.html
new file mode 100644
index 0000000000..e30f1d2fa0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.several-complex-expected.html">
+<meta name=fuzzy content="maxDifference=0-3; totalPixels=0-6318">
+<title>Canvas test: 2d.layer.several-complex</title>
+<h1>2d.layer.several-complex</h1>
+<p class="desc">Test to ensure beginlayer works for filter, alpha and shadow, even with consecutive layers.</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(500, 500);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 95, 70);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'orange';
+ ctx.shadowBlur = 3
+
+ for (let i = 0; i < 5; i++) {
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60 + i, 40 + i, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(80 + i, 60 + i, 75, 50);
+
+ ctx.endLayer();
+ }
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.w.html
new file mode 100644
index 0000000000..e00de63507
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.several-complex.w.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.several-complex-expected.html">
+<meta name=fuzzy content="maxDifference=0-3; totalPixels=0-6318">
+<title>Canvas test: 2d.layer.several-complex</title>
+<h1>2d.layer.several-complex</h1>
+<p class="desc">Test to ensure beginlayer works for filter, alpha and shadow, even with consecutive layers.</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(500, 500);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 95, 70);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'orange';
+ ctx.shadowBlur = 3
+
+ for (let i = 0; i < 5; i++) {
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60 + i, 40 + i, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(80 + i, 60 + i, 75, 50);
+
+ ctx.endLayer();
+ }
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html
new file mode 100644
index 0000000000..cc10684a9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-expected.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ // No clipping.
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html
new file mode 100644
index 0000000000..377dd55ef6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html
new file mode 100644
index 0000000000..98262f53b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.w.html
new file mode 100644
index 0000000000..90b4332f94
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance-with-clipping.w.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.long-distance-with-clipping-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.html
new file mode 100644
index 0000000000..eea9b5dc25
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.long-distance-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.w.html
new file mode 100644
index 0000000000..e4422558cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance.w.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.long-distance-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.long-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.long-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 10000;
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html
new file mode 100644
index 0000000000..8980708dd1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-expected.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ // No clipping.
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html
new file mode 100644
index 0000000000..024fc8c9a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html
new file mode 100644
index 0000000000..d5f5b0c8ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.w.html
new file mode 100644
index 0000000000..acbf09edec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance-with-clipping.w.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.short-distance-with-clipping-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance-with-clipping</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.html
new file mode 100644
index 0000000000..a1c4689f7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.short-distance-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.w.html
new file mode 100644
index 0000000000..2e39091f3d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.short-distance.w.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.shadow-from-outside-canvas.short-distance-expected.html">
+<title>Canvas test: 2d.layer.shadow-from-outside-canvas.short-distance</title>
+<h1>2d.layer.shadow-from-outside-canvas.short-distance</h1>
+<p class="desc">Checks shadow produced by object drawn outside the canvas</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ const delta = 1;
+
+ // No clipping.
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -(200 + delta),
+ dy: -(200 + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(200 + delta, 200 + delta, 100, 100);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.html
new file mode 100644
index 0000000000..0a6e195ca8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.beginLayer-endLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.beginLayer-endLayer</h1>
+<p class="desc">No exception raised on beginLayer() + endLayer().</p>
+
+
+<script>
+var t = async_test("No exception raised on beginLayer() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ ctx.save();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.worker.js
new file mode 100644
index 0000000000..a10bcd98b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-endLayer.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.beginLayer-endLayer
+// Description:No exception raised on beginLayer() + endLayer().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on beginLayer() + endLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ ctx.save();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.html
new file mode 100644
index 0000000000..12abcc5270
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.beginLayer-save</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.beginLayer-save</h1>
+<p class="desc">No exception raised on beginLayer() + save().</p>
+
+
+<script>
+var t = async_test("No exception raised on beginLayer() + save().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ ctx.save();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.worker.js
new file mode 100644
index 0000000000..03fbeeb4f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer-save.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.beginLayer-save
+// Description:No exception raised on beginLayer() + save().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on beginLayer() + save().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ ctx.save();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.html
new file mode 100644
index 0000000000..2178138e8d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.beginLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.beginLayer</h1>
+<p class="desc">No exception raised on lone beginLayer() calls.</p>
+
+
+<script>
+var t = async_test("No exception raised on lone beginLayer() calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.worker.js
new file mode 100644
index 0000000000..e64be136d7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.beginLayer.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.beginLayer
+// Description:No exception raised on lone beginLayer() calls.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on lone beginLayer() calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.beginLayer();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.html
new file mode 100644
index 0000000000..156dd5abbd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.restore</h1>
+<p class="desc">No exception raised on lone restore() calls.</p>
+
+
+<script>
+var t = async_test("No exception raised on lone restore() calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.worker.js
new file mode 100644
index 0000000000..7417d12abe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.restore.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.restore
+// Description:No exception raised on lone restore() calls.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on lone restore() calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.html
new file mode 100644
index 0000000000..afe735764e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.save-beginLayer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.save-beginLayer</h1>
+<p class="desc">No exception raised on save() + beginLayer().</p>
+
+
+<script>
+var t = async_test("No exception raised on save() + beginLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ ctx.beginLayer();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.worker.js
new file mode 100644
index 0000000000..773ba77a15
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save-beginLayer.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.save-beginLayer
+// Description:No exception raised on save() + beginLayer().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on save() + beginLayer().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ ctx.beginLayer();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.html
new file mode 100644
index 0000000000..2b2de23bb8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.save</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.save</h1>
+<p class="desc">No exception raised on lone save() calls.</p>
+
+
+<script>
+var t = async_test("No exception raised on lone save() calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.worker.js
new file mode 100644
index 0000000000..5bbf0386fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.save
+// Description:No exception raised on lone save() calls.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on lone save() calls.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.html
new file mode 100644
index 0000000000..ec5aa6455e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.save_reset_restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.save_reset_restore</h1>
+<p class="desc">No exception raised on save() + reset() + restore().</p>
+
+
+<script>
+var t = async_test("No exception raised on save() + reset() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ ctx.reset();
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.worker.js
new file mode 100644
index 0000000000..3636c94357
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_reset_restore.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.save_reset_restore
+// Description:No exception raised on save() + reset() + restore().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on save() + reset() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ ctx.reset();
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.html
new file mode 100644
index 0000000000..1682bca91c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.layer.valid-calls.save_restore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.layer.valid-calls.save_restore</h1>
+<p class="desc">No exception raised on save() + restore().</p>
+
+
+<script>
+var t = async_test("No exception raised on save() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.worker.js
new file mode 100644
index 0000000000..8607722df7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.valid-calls.save_restore.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.layer.valid-calls.save_restore
+// Description:No exception raised on save() + restore().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("No exception raised on save() + restore().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.save();
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.html
new file mode 100644
index 0000000000..145e145cb4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cap.butt</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cap.butt</h1>
+<p class="desc">lineCap 'butt' is rendered correctly</p>
+
+
+<script>
+var t = async_test("lineCap 'butt' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'butt';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 25,14, 0,255,0,255);
+ _assertPixel(canvas, 25,15, 0,255,0,255);
+ _assertPixel(canvas, 25,16, 0,255,0,255);
+ _assertPixel(canvas, 25,34, 0,255,0,255);
+ _assertPixel(canvas, 25,35, 0,255,0,255);
+ _assertPixel(canvas, 25,36, 0,255,0,255);
+
+ _assertPixel(canvas, 75,14, 0,255,0,255);
+ _assertPixel(canvas, 75,15, 0,255,0,255);
+ _assertPixel(canvas, 75,16, 0,255,0,255);
+ _assertPixel(canvas, 75,34, 0,255,0,255);
+ _assertPixel(canvas, 75,35, 0,255,0,255);
+ _assertPixel(canvas, 75,36, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.worker.js
new file mode 100644
index 0000000000..127393790c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.butt.worker.js
@@ -0,0 +1,56 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cap.butt
+// Description:lineCap 'butt' is rendered correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineCap 'butt' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'butt';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 25,14, 0,255,0,255);
+ _assertPixel(canvas, 25,15, 0,255,0,255);
+ _assertPixel(canvas, 25,16, 0,255,0,255);
+ _assertPixel(canvas, 25,34, 0,255,0,255);
+ _assertPixel(canvas, 25,35, 0,255,0,255);
+ _assertPixel(canvas, 25,36, 0,255,0,255);
+
+ _assertPixel(canvas, 75,14, 0,255,0,255);
+ _assertPixel(canvas, 75,15, 0,255,0,255);
+ _assertPixel(canvas, 75,16, 0,255,0,255);
+ _assertPixel(canvas, 75,34, 0,255,0,255);
+ _assertPixel(canvas, 75,35, 0,255,0,255);
+ _assertPixel(canvas, 75,36, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.html
new file mode 100644
index 0000000000..edddeb08e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cap.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cap.closed</h1>
+<p class="desc">Line caps are not drawn at the corners of an unclosed rectangle</p>
+
+
+<script>
+var t = async_test("Line caps are not drawn at the corners of an unclosed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.worker.js
new file mode 100644
index 0000000000..b8357316e4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.closed.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cap.closed
+// Description:Line caps are not drawn at the corners of an unclosed rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Line caps are not drawn at the corners of an unclosed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.html
new file mode 100644
index 0000000000..2054bbc515
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cap.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cap.invalid</h1>
+<p class="desc">Setting lineCap to invalid values is ignored</p>
+
+
+<script>
+var t = async_test("Setting lineCap to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineCap = 'butt'
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'invalid';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'ROUND';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round\0';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round ';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = "";
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'bevel';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.worker.js
new file mode 100644
index 0000000000..813ceb7f66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.invalid.worker.js
@@ -0,0 +1,47 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cap.invalid
+// Description:Setting lineCap to invalid values is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting lineCap to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineCap = 'butt'
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'invalid';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'ROUND';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round\0';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round ';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = "";
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'bevel';
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.html
new file mode 100644
index 0000000000..f26fbc686c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cap.open</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cap.open</h1>
+<p class="desc">Line caps are drawn at the corners of an unclosed rectangle</p>
+
+
+<script>
+var t = async_test("Line caps are drawn at the corners of an unclosed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.lineTo(200, 200);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.worker.js
new file mode 100644
index 0000000000..169010ac2a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.open.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cap.open
+// Description:Line caps are drawn at the corners of an unclosed rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Line caps are drawn at the corners of an unclosed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.lineTo(200, 200);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.html
new file mode 100644
index 0000000000..31f5ba5423
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cap.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cap.round</h1>
+<p class="desc">lineCap 'round' is rendered correctly</p>
+
+
+<script>
+var t = async_test("lineCap 'round' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineCap = 'round';
+ ctx.lineWidth = 20;
+
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(35-tol, 15);
+ ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
+ ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(85+tol, 15);
+ ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
+ ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
+ ctx.fill();
+
+ _assertPixel(canvas, 17,6, 0,255,0,255);
+ _assertPixel(canvas, 25,6, 0,255,0,255);
+ _assertPixel(canvas, 32,6, 0,255,0,255);
+ _assertPixel(canvas, 17,43, 0,255,0,255);
+ _assertPixel(canvas, 25,43, 0,255,0,255);
+ _assertPixel(canvas, 32,43, 0,255,0,255);
+
+ _assertPixel(canvas, 67,6, 0,255,0,255);
+ _assertPixel(canvas, 75,6, 0,255,0,255);
+ _assertPixel(canvas, 82,6, 0,255,0,255);
+ _assertPixel(canvas, 67,43, 0,255,0,255);
+ _assertPixel(canvas, 75,43, 0,255,0,255);
+ _assertPixel(canvas, 82,43, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.worker.js
new file mode 100644
index 0000000000..a8d9c1b92f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.round.worker.js
@@ -0,0 +1,72 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cap.round
+// Description:lineCap 'round' is rendered correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineCap 'round' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineCap = 'round';
+ ctx.lineWidth = 20;
+
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(35-tol, 15);
+ ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
+ ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(85+tol, 15);
+ ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
+ ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
+ ctx.fill();
+
+ _assertPixel(canvas, 17,6, 0,255,0,255);
+ _assertPixel(canvas, 25,6, 0,255,0,255);
+ _assertPixel(canvas, 32,6, 0,255,0,255);
+ _assertPixel(canvas, 17,43, 0,255,0,255);
+ _assertPixel(canvas, 25,43, 0,255,0,255);
+ _assertPixel(canvas, 32,43, 0,255,0,255);
+
+ _assertPixel(canvas, 67,6, 0,255,0,255);
+ _assertPixel(canvas, 75,6, 0,255,0,255);
+ _assertPixel(canvas, 82,6, 0,255,0,255);
+ _assertPixel(canvas, 67,43, 0,255,0,255);
+ _assertPixel(canvas, 75,43, 0,255,0,255);
+ _assertPixel(canvas, 82,43, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.html
new file mode 100644
index 0000000000..0d2988877d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cap.square</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cap.square</h1>
+<p class="desc">lineCap 'square' is rendered correctly</p>
+
+
+<script>
+var t = async_test("lineCap 'square' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 5, 20, 40);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 5, 20, 40);
+
+ _assertPixel(canvas, 25,4, 0,255,0,255);
+ _assertPixel(canvas, 25,5, 0,255,0,255);
+ _assertPixel(canvas, 25,6, 0,255,0,255);
+ _assertPixel(canvas, 25,44, 0,255,0,255);
+ _assertPixel(canvas, 25,45, 0,255,0,255);
+ _assertPixel(canvas, 25,46, 0,255,0,255);
+
+ _assertPixel(canvas, 75,4, 0,255,0,255);
+ _assertPixel(canvas, 75,5, 0,255,0,255);
+ _assertPixel(canvas, 75,6, 0,255,0,255);
+ _assertPixel(canvas, 75,44, 0,255,0,255);
+ _assertPixel(canvas, 75,45, 0,255,0,255);
+ _assertPixel(canvas, 75,46, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.worker.js
new file mode 100644
index 0000000000..6776e9891b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.square.worker.js
@@ -0,0 +1,56 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cap.square
+// Description:lineCap 'square' is rendered correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineCap 'square' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 5, 20, 40);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 5, 20, 40);
+
+ _assertPixel(canvas, 25,4, 0,255,0,255);
+ _assertPixel(canvas, 25,5, 0,255,0,255);
+ _assertPixel(canvas, 25,6, 0,255,0,255);
+ _assertPixel(canvas, 25,44, 0,255,0,255);
+ _assertPixel(canvas, 25,45, 0,255,0,255);
+ _assertPixel(canvas, 25,46, 0,255,0,255);
+
+ _assertPixel(canvas, 75,4, 0,255,0,255);
+ _assertPixel(canvas, 75,5, 0,255,0,255);
+ _assertPixel(canvas, 75,6, 0,255,0,255);
+ _assertPixel(canvas, 75,44, 0,255,0,255);
+ _assertPixel(canvas, 75,45, 0,255,0,255);
+ _assertPixel(canvas, 75,46, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.html
new file mode 100644
index 0000000000..6334891f56
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cap.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cap.valid</h1>
+<p class="desc">Setting lineCap to valid values works</p>
+
+
+<script>
+var t = async_test("Setting lineCap to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineCap = 'butt'
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'round';
+ _assertSame(ctx.lineCap, 'round', "ctx.lineCap", "'round'");
+
+ ctx.lineCap = 'square';
+ _assertSame(ctx.lineCap, 'square', "ctx.lineCap", "'square'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.worker.js
new file mode 100644
index 0000000000..0010fd61dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cap.valid.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cap.valid
+// Description:Setting lineCap to valid values works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting lineCap to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineCap = 'butt'
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+
+ ctx.lineCap = 'round';
+ _assertSame(ctx.lineCap, 'round', "ctx.lineCap", "'round'");
+
+ ctx.lineCap = 'square';
+ _assertSame(ctx.lineCap, 'square', "ctx.lineCap", "'square'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.html
new file mode 100644
index 0000000000..83e2a758fd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.cross</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.cross</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(110, 50);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(100, 60);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.worker.js
new file mode 100644
index 0000000000..5dc95c25f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.cross.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.cross
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(110, 50);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(100, 60);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.html
new file mode 100644
index 0000000000..7f50257288
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.defaults</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.defaults</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+ _assertSame(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'");
+ _assertSame(ctx.miterLimit, 10, "ctx.miterLimit", "10");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.worker.js
new file mode 100644
index 0000000000..1a59b81027
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.defaults.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.defaults
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+ _assertSame(ctx.lineCap, 'butt', "ctx.lineCap", "'butt'");
+ _assertSame(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'");
+ _assertSame(ctx.miterLimit, 10, "ctx.miterLimit", "10");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.html
new file mode 100644
index 0000000000..0d1aa4be30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.fill.noop</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.fill.noop</h1>
+<p class="desc">Filling a line draws nothing</p>
+
+
+<script>
+var t = async_test("Filling a line draws nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 20;
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(90, 30);
+ ctx.fill();
+ _assertPixel(canvas, 50,24, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,26, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.worker.js
new file mode 100644
index 0000000000..e3e8c14b3f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.fill.noop.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.fill.noop
+// Description:Filling a line draws nothing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Filling a line draws nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 20;
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(90, 30);
+ ctx.fill();
+ _assertPixel(canvas, 50,24, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,26, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.html
new file mode 100644
index 0000000000..fa67e3b3f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.invalid.strokestyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.invalid.strokestyle</h1>
+<p class="desc">Verify correct behavior of canvas on an invalid strokeStyle()</p>
+
+
+<script>
+var t = async_test("Verify correct behavior of canvas on an invalid strokeStyle()");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = 'rgb(0, 255, 0)';
+ ctx.strokeStyle = 'nonsense';
+ ctx.lineWidth = 200;
+ ctx.moveTo(0,100);
+ ctx.lineTo(200,100);
+ ctx.stroke();
+ var imageData = ctx.getImageData(0, 0, 200, 200);
+ var imgdata = imageData.data;
+ _assert(imgdata[4] == 0, "imgdata[\""+(4)+"\"] == 0");
+ _assert(imgdata[5] == 255, "imgdata[\""+(5)+"\"] == 255");
+ _assert(imgdata[6] == 0, "imgdata[\""+(6)+"\"] == 0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.worker.js
new file mode 100644
index 0000000000..5726b1835a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.invalid.strokestyle
+// Description:Verify correct behavior of canvas on an invalid strokeStyle()
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify correct behavior of canvas on an invalid strokeStyle()");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.strokeStyle = 'rgb(0, 255, 0)';
+ ctx.strokeStyle = 'nonsense';
+ ctx.lineWidth = 200;
+ ctx.moveTo(0,100);
+ ctx.lineTo(200,100);
+ ctx.stroke();
+ var imageData = ctx.getImageData(0, 0, 200, 200);
+ var imgdata = imageData.data;
+ _assert(imgdata[4] == 0, "imgdata[\""+(4)+"\"] == 0");
+ _assert(imgdata[5] == 255, "imgdata[\""+(5)+"\"] == 255");
+ _assert(imgdata[6] == 0, "imgdata[\""+(6)+"\"] == 0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.html
new file mode 100644
index 0000000000..70e3896281
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.bevel</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.bevel</h1>
+<p class="desc">lineJoin 'bevel' is rendered correctly</p>
+
+
+<script>
+var t = async_test("lineJoin 'bevel' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.lineTo(40-tol, 20);
+ ctx.lineTo(30, 10+tol);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.lineTo(90+tol, 20);
+ ctx.lineTo(80, 10-tol);
+ ctx.fill();
+
+ _assertPixel(canvas, 34,16, 0,255,0,255);
+ _assertPixel(canvas, 34,15, 0,255,0,255);
+ _assertPixel(canvas, 35,15, 0,255,0,255);
+ _assertPixel(canvas, 36,15, 0,255,0,255);
+ _assertPixel(canvas, 36,14, 0,255,0,255);
+
+ _assertPixel(canvas, 84,16, 0,255,0,255);
+ _assertPixel(canvas, 84,15, 0,255,0,255);
+ _assertPixel(canvas, 85,15, 0,255,0,255);
+ _assertPixel(canvas, 86,15, 0,255,0,255);
+ _assertPixel(canvas, 86,14, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.worker.js
new file mode 100644
index 0000000000..efd884debe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.bevel.worker.js
@@ -0,0 +1,75 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.bevel
+// Description:lineJoin 'bevel' is rendered correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineJoin 'bevel' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.lineTo(40-tol, 20);
+ ctx.lineTo(30, 10+tol);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.lineTo(90+tol, 20);
+ ctx.lineTo(80, 10-tol);
+ ctx.fill();
+
+ _assertPixel(canvas, 34,16, 0,255,0,255);
+ _assertPixel(canvas, 34,15, 0,255,0,255);
+ _assertPixel(canvas, 35,15, 0,255,0,255);
+ _assertPixel(canvas, 36,15, 0,255,0,255);
+ _assertPixel(canvas, 36,14, 0,255,0,255);
+
+ _assertPixel(canvas, 84,16, 0,255,0,255);
+ _assertPixel(canvas, 84,15, 0,255,0,255);
+ _assertPixel(canvas, 85,15, 0,255,0,255);
+ _assertPixel(canvas, 86,15, 0,255,0,255);
+ _assertPixel(canvas, 86,14, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.html
new file mode 100644
index 0000000000..60650adeb3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.closed</h1>
+<p class="desc">Line joins are drawn at the corner of a closed rectangle</p>
+
+
+<script>
+var t = async_test("Line joins are drawn at the corner of a closed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.worker.js
new file mode 100644
index 0000000000..4882311961
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.closed.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.closed
+// Description:Line joins are drawn at the corner of a closed rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Line joins are drawn at the corner of a closed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.html
new file mode 100644
index 0000000000..be1f7e393e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.invalid</h1>
+<p class="desc">Setting lineJoin to invalid values is ignored</p>
+
+
+<script>
+var t = async_test("Setting lineJoin to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineJoin = 'bevel'
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'invalid';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'ROUND';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round\0';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round ';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = "";
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'butt';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.worker.js
new file mode 100644
index 0000000000..aa5a35c0c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.invalid.worker.js
@@ -0,0 +1,47 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.invalid
+// Description:Setting lineJoin to invalid values is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting lineJoin to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineJoin = 'bevel'
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'invalid';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'ROUND';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round\0';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round ';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = "";
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'butt';
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.html
new file mode 100644
index 0000000000..c26e883c40
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.miter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.miter</h1>
+<p class="desc">lineJoin 'miter' is rendered correctly</p>
+
+
+<script>
+var t = async_test("lineJoin 'miter' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 30, 20);
+ ctx.fillRect(20, 10, 20, 30);
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 30, 20);
+ ctx.fillRect(70, 10, 20, 30);
+
+ _assertPixel(canvas, 38,12, 0,255,0,255);
+ _assertPixel(canvas, 39,11, 0,255,0,255);
+ _assertPixel(canvas, 40,10, 0,255,0,255);
+ _assertPixel(canvas, 41,9, 0,255,0,255);
+ _assertPixel(canvas, 42,8, 0,255,0,255);
+
+ _assertPixel(canvas, 88,12, 0,255,0,255);
+ _assertPixel(canvas, 89,11, 0,255,0,255);
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 91,9, 0,255,0,255);
+ _assertPixel(canvas, 92,8, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.worker.js
new file mode 100644
index 0000000000..7b70000100
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.miter.worker.js
@@ -0,0 +1,66 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.miter
+// Description:lineJoin 'miter' is rendered correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineJoin 'miter' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 30, 20);
+ ctx.fillRect(20, 10, 20, 30);
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 30, 20);
+ ctx.fillRect(70, 10, 20, 30);
+
+ _assertPixel(canvas, 38,12, 0,255,0,255);
+ _assertPixel(canvas, 39,11, 0,255,0,255);
+ _assertPixel(canvas, 40,10, 0,255,0,255);
+ _assertPixel(canvas, 41,9, 0,255,0,255);
+ _assertPixel(canvas, 42,8, 0,255,0,255);
+
+ _assertPixel(canvas, 88,12, 0,255,0,255);
+ _assertPixel(canvas, 89,11, 0,255,0,255);
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 91,9, 0,255,0,255);
+ _assertPixel(canvas, 92,8, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.html
new file mode 100644
index 0000000000..d801e5c367
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.open</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.open</h1>
+<p class="desc">Line joins are not drawn at the corner of an unclosed rectangle</p>
+
+
+<script>
+var t = async_test("Line joins are not drawn at the corner of an unclosed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.worker.js
new file mode 100644
index 0000000000..2a1242436d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.open.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.open
+// Description:Line joins are not drawn at the corner of an unclosed rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Line joins are not drawn at the corner of an unclosed rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.html
new file mode 100644
index 0000000000..0826406b9d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.parallel</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.parallel</h1>
+<p class="desc">Line joins are drawn at 180-degree joins</p>
+
+
+<script>
+var t = async_test("Line joins are drawn at 180-degree joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 300;
+ ctx.lineJoin = 'round';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(-100, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.worker.js
new file mode 100644
index 0000000000..f5b67dc5a2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.parallel.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.parallel
+// Description:Line joins are drawn at 180-degree joins
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Line joins are drawn at 180-degree joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 300;
+ ctx.lineJoin = 'round';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(-100, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.html
new file mode 100644
index 0000000000..70f6a8e517
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.round</h1>
+<p class="desc">lineJoin 'round' is rendered correctly</p>
+
+
+<script>
+var t = async_test("lineJoin 'round' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'round';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ _assertPixel(canvas, 36,14, 0,255,0,255);
+ _assertPixel(canvas, 36,13, 0,255,0,255);
+ _assertPixel(canvas, 37,13, 0,255,0,255);
+ _assertPixel(canvas, 38,13, 0,255,0,255);
+ _assertPixel(canvas, 38,12, 0,255,0,255);
+
+ _assertPixel(canvas, 86,14, 0,255,0,255);
+ _assertPixel(canvas, 86,13, 0,255,0,255);
+ _assertPixel(canvas, 87,13, 0,255,0,255);
+ _assertPixel(canvas, 88,13, 0,255,0,255);
+ _assertPixel(canvas, 88,12, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.worker.js
new file mode 100644
index 0000000000..33b135d604
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.round.worker.js
@@ -0,0 +1,73 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.round
+// Description:lineJoin 'round' is rendered correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineJoin 'round' is rendered correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'round';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ _assertPixel(canvas, 36,14, 0,255,0,255);
+ _assertPixel(canvas, 36,13, 0,255,0,255);
+ _assertPixel(canvas, 37,13, 0,255,0,255);
+ _assertPixel(canvas, 38,13, 0,255,0,255);
+ _assertPixel(canvas, 38,12, 0,255,0,255);
+
+ _assertPixel(canvas, 86,14, 0,255,0,255);
+ _assertPixel(canvas, 86,13, 0,255,0,255);
+ _assertPixel(canvas, 87,13, 0,255,0,255);
+ _assertPixel(canvas, 88,13, 0,255,0,255);
+ _assertPixel(canvas, 88,12, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.html
new file mode 100644
index 0000000000..3b3935d1f7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.join.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.join.valid</h1>
+<p class="desc">Setting lineJoin to valid values works</p>
+
+
+<script>
+var t = async_test("Setting lineJoin to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineJoin = 'bevel'
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'round';
+ _assertSame(ctx.lineJoin, 'round', "ctx.lineJoin", "'round'");
+
+ ctx.lineJoin = 'miter';
+ _assertSame(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.worker.js
new file mode 100644
index 0000000000..d1bdfd8845
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.join.valid.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.join.valid
+// Description:Setting lineJoin to valid values works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting lineJoin to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineJoin = 'bevel'
+ _assertSame(ctx.lineJoin, 'bevel', "ctx.lineJoin", "'bevel'");
+
+ ctx.lineJoin = 'round';
+ _assertSame(ctx.lineJoin, 'round', "ctx.lineJoin", "'round'");
+
+ ctx.lineJoin = 'miter';
+ _assertSame(ctx.lineJoin, 'miter', "ctx.lineJoin", "'miter'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.html
new file mode 100644
index 0000000000..587062ed12
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.acute</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.acute</h1>
+<p class="desc">Miter joins are drawn correctly with acute angles</p>
+
+
+<script>
+var t = async_test("Miter joins are drawn correctly with acute angles");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 2.614;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 2.613;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.worker.js
new file mode 100644
index 0000000000..0ab5c9050c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.acute.worker.js
@@ -0,0 +1,47 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.acute
+// Description:Miter joins are drawn correctly with acute angles
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Miter joins are drawn correctly with acute angles");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 2.614;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 2.613;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.html
new file mode 100644
index 0000000000..1ae5c55aef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.exceeded</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.exceeded</h1>
+<p class="desc">Miter joins are not drawn when the miter limit is exceeded</p>
+
+
+<script>
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.worker.js
new file mode 100644
index 0000000000..41c4716c88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.exceeded.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.exceeded
+// Description:Miter joins are not drawn when the miter limit is exceeded
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.html
new file mode 100644
index 0000000000..eacd95b811
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.invalid</h1>
+<p class="desc">Setting miterLimit to invalid values is ignored</p>
+
+
+<script>
+var t = async_test("Setting miterLimit to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.miterLimit = 1.5;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 0;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -1;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = Infinity;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -Infinity;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = NaN;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 'string';
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = true;
+ _assertSame(ctx.miterLimit, 1, "ctx.miterLimit", "1");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = false;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.worker.js
new file mode 100644
index 0000000000..62f250670c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.invalid.worker.js
@@ -0,0 +1,55 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.invalid
+// Description:Setting miterLimit to invalid values is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting miterLimit to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.miterLimit = 1.5;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 0;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -1;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = Infinity;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -Infinity;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = NaN;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 'string';
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = true;
+ _assertSame(ctx.miterLimit, 1, "ctx.miterLimit", "1");
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = false;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.html
new file mode 100644
index 0000000000..bad3cedc0e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.lineedge</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.lineedge</h1>
+<p class="desc">Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle</p>
+
+
+<script>
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.strokeRect(100, 25, 200, 0);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.worker.js
new file mode 100644
index 0000000000..2b61bc8975
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.lineedge.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.lineedge
+// Description:Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.strokeRect(100, 25, 200, 0);
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.html
new file mode 100644
index 0000000000..efab533fba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.obtuse</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.obtuse</h1>
+<p class="desc">Miter joins are drawn correctly with obtuse angles</p>
+
+
+<script>
+var t = async_test("Miter joins are drawn correctly with obtuse angles");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 1600;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.083;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.082;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.worker.js
new file mode 100644
index 0000000000..42b1cd37b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.obtuse.worker.js
@@ -0,0 +1,47 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.obtuse
+// Description:Miter joins are drawn correctly with obtuse angles
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Miter joins are drawn correctly with obtuse angles");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 1600;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.083;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.082;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.html
new file mode 100644
index 0000000000..5bb4e63230
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.rightangle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.rightangle</h1>
+<p class="desc">Miter joins are not drawn when the miter limit is exceeded, on exact right angles</p>
+
+
+<script>
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded, on exact right angles");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 200);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.worker.js
new file mode 100644
index 0000000000..42e995deed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.rightangle.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.rightangle
+// Description:Miter joins are not drawn when the miter limit is exceeded, on exact right angles
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Miter joins are not drawn when the miter limit is exceeded, on exact right angles");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 200);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.html
new file mode 100644
index 0000000000..3c569ea655
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.valid</h1>
+<p class="desc">Setting miterLimit to valid values works</p>
+
+
+<script>
+var t = async_test("Setting miterLimit to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.miterLimit = 1.5;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = "1e1";
+ _assertSame(ctx.miterLimit, 10, "ctx.miterLimit", "10");
+
+ ctx.miterLimit = 1/1024;
+ _assertSame(ctx.miterLimit, 1/1024, "ctx.miterLimit", "1/1024");
+
+ ctx.miterLimit = 1000;
+ _assertSame(ctx.miterLimit, 1000, "ctx.miterLimit", "1000");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.worker.js
new file mode 100644
index 0000000000..cb0548abd0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.valid.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.valid
+// Description:Setting miterLimit to valid values works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting miterLimit to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.miterLimit = 1.5;
+ _assertSame(ctx.miterLimit, 1.5, "ctx.miterLimit", "1.5");
+
+ ctx.miterLimit = "1e1";
+ _assertSame(ctx.miterLimit, 10, "ctx.miterLimit", "10");
+
+ ctx.miterLimit = 1/1024;
+ _assertSame(ctx.miterLimit, 1/1024, "ctx.miterLimit", "1/1024");
+
+ ctx.miterLimit = 1000;
+ _assertSame(ctx.miterLimit, 1000, "ctx.miterLimit", "1000");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.html
new file mode 100644
index 0000000000..da87cf4a29
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.miter.within</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.miter.within</h1>
+<p class="desc">Miter joins are drawn when the miter limit is not quite exceeded</p>
+
+
+<script>
+var t = async_test("Miter joins are drawn when the miter limit is not quite exceeded");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.416;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.worker.js
new file mode 100644
index 0000000000..1d9aacb817
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.miter.within.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.miter.within
+// Description:Miter joins are drawn when the miter limit is not quite exceeded
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Miter joins are drawn when the miter limit is not quite exceeded");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.416;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.html
new file mode 100644
index 0000000000..d3d13ece09
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.union</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.union</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 24);
+ ctx.lineTo(100, 25);
+ ctx.lineTo(0, 26);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 25,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 25,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.worker.js
new file mode 100644
index 0000000000..f2c7b2c4ce
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.union.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.union
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 24);
+ ctx.lineTo(100, 25);
+ ctx.lineTo(0, 26);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 25,1, 0,255,0,255);
+ _assertPixel(canvas, 48,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 25,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.html
new file mode 100644
index 0000000000..88e38294bf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.width.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.width.basic</h1>
+<p class="desc">lineWidth determines the width of line strokes</p>
+
+
+<script>
+var t = async_test("lineWidth determines the width of line strokes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 20;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 14,25, 0,255,0,255);
+ _assertPixel(canvas, 15,25, 0,255,0,255);
+ _assertPixel(canvas, 16,25, 0,255,0,255);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 34,25, 0,255,0,255);
+ _assertPixel(canvas, 35,25, 0,255,0,255);
+ _assertPixel(canvas, 36,25, 0,255,0,255);
+
+ _assertPixel(canvas, 64,25, 0,255,0,255);
+ _assertPixel(canvas, 65,25, 0,255,0,255);
+ _assertPixel(canvas, 66,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 84,25, 0,255,0,255);
+ _assertPixel(canvas, 85,25, 0,255,0,255);
+ _assertPixel(canvas, 86,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.worker.js
new file mode 100644
index 0000000000..012d9b11bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.basic.worker.js
@@ -0,0 +1,58 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.width.basic
+// Description:lineWidth determines the width of line strokes
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineWidth determines the width of line strokes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 20;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 14,25, 0,255,0,255);
+ _assertPixel(canvas, 15,25, 0,255,0,255);
+ _assertPixel(canvas, 16,25, 0,255,0,255);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 34,25, 0,255,0,255);
+ _assertPixel(canvas, 35,25, 0,255,0,255);
+ _assertPixel(canvas, 36,25, 0,255,0,255);
+
+ _assertPixel(canvas, 64,25, 0,255,0,255);
+ _assertPixel(canvas, 65,25, 0,255,0,255);
+ _assertPixel(canvas, 66,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 84,25, 0,255,0,255);
+ _assertPixel(canvas, 85,25, 0,255,0,255);
+ _assertPixel(canvas, 86,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.html
new file mode 100644
index 0000000000..481a316822
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.width.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.width.invalid</h1>
+<p class="desc">Setting lineWidth to invalid values is ignored</p>
+
+
+<script>
+var t = async_test("Setting lineWidth to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 1.5;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 0;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -1;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = Infinity;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -Infinity;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = NaN;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 'string';
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = true;
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = false;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.worker.js
new file mode 100644
index 0000000000..3a10cb48e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.invalid.worker.js
@@ -0,0 +1,55 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.width.invalid
+// Description:Setting lineWidth to invalid values is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting lineWidth to invalid values is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 1.5;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 0;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -1;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = Infinity;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -Infinity;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = NaN;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 'string';
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = true;
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = false;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.html
new file mode 100644
index 0000000000..9ac77a9c49
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.width.scaledefault</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.width.scaledefault</h1>
+<p class="desc">Default lineWidth strokes are affected by scale transformations</p>
+
+
+<script>
+var t = async_test("Default lineWidth strokes are affected by scale transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(50, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.moveTo(0, 0.5);
+ ctx.lineTo(2, 0.5);
+ ctx.stroke();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 50,5, 0,255,0,255);
+ _assertPixel(canvas, 50,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.worker.js
new file mode 100644
index 0000000000..8d8089476b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.scaledefault.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.width.scaledefault
+// Description:Default lineWidth strokes are affected by scale transformations
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Default lineWidth strokes are affected by scale transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(50, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.moveTo(0, 0.5);
+ ctx.lineTo(2, 0.5);
+ ctx.stroke();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 50,5, 0,255,0,255);
+ _assertPixel(canvas, 50,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.html
new file mode 100644
index 0000000000..ea8f285dc4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.width.transformed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.width.transformed</h1>
+<p class="desc">Line stroke widths are affected by scale transformations</p>
+
+
+<script>
+var t = async_test("Line stroke widths are affected by scale transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 4;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.save();
+ ctx.scale(5, 1);
+ ctx.beginPath();
+ ctx.moveTo(5, 15);
+ ctx.lineTo(5, 35);
+ ctx.stroke();
+ ctx.restore();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.save();
+ ctx.scale(-5, 1);
+ ctx.beginPath();
+ ctx.moveTo(-15, 15);
+ ctx.lineTo(-15, 35);
+ ctx.stroke();
+ ctx.restore();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 14,25, 0,255,0,255);
+ _assertPixel(canvas, 15,25, 0,255,0,255);
+ _assertPixel(canvas, 16,25, 0,255,0,255);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 34,25, 0,255,0,255);
+ _assertPixel(canvas, 35,25, 0,255,0,255);
+ _assertPixel(canvas, 36,25, 0,255,0,255);
+
+ _assertPixel(canvas, 64,25, 0,255,0,255);
+ _assertPixel(canvas, 65,25, 0,255,0,255);
+ _assertPixel(canvas, 66,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 84,25, 0,255,0,255);
+ _assertPixel(canvas, 85,25, 0,255,0,255);
+ _assertPixel(canvas, 86,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.worker.js
new file mode 100644
index 0000000000..67fc0a29bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.worker.js
@@ -0,0 +1,64 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.width.transformed
+// Description:Line stroke widths are affected by scale transformations
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Line stroke widths are affected by scale transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 4;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.save();
+ ctx.scale(5, 1);
+ ctx.beginPath();
+ ctx.moveTo(5, 15);
+ ctx.lineTo(5, 35);
+ ctx.stroke();
+ ctx.restore();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.save();
+ ctx.scale(-5, 1);
+ ctx.beginPath();
+ ctx.moveTo(-15, 15);
+ ctx.lineTo(-15, 35);
+ ctx.stroke();
+ ctx.restore();
+ ctx.fillRect(65, 15, 20, 20);
+
+ _assertPixel(canvas, 14,25, 0,255,0,255);
+ _assertPixel(canvas, 15,25, 0,255,0,255);
+ _assertPixel(canvas, 16,25, 0,255,0,255);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 34,25, 0,255,0,255);
+ _assertPixel(canvas, 35,25, 0,255,0,255);
+ _assertPixel(canvas, 36,25, 0,255,0,255);
+
+ _assertPixel(canvas, 64,25, 0,255,0,255);
+ _assertPixel(canvas, 65,25, 0,255,0,255);
+ _assertPixel(canvas, 66,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ _assertPixel(canvas, 84,25, 0,255,0,255);
+ _assertPixel(canvas, 85,25, 0,255,0,255);
+ _assertPixel(canvas, 86,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.html b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.html
new file mode 100644
index 0000000000..813433da3f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.line.width.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.line.width.valid</h1>
+<p class="desc">Setting lineWidth to valid values works</p>
+
+
+<script>
+var t = async_test("Setting lineWidth to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 1.5;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = "1e1";
+ _assertSame(ctx.lineWidth, 10, "ctx.lineWidth", "10");
+
+ ctx.lineWidth = 1/1024;
+ _assertSame(ctx.lineWidth, 1/1024, "ctx.lineWidth", "1/1024");
+
+ ctx.lineWidth = 1000;
+ _assertSame(ctx.lineWidth, 1000, "ctx.lineWidth", "1000");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.worker.js
new file mode 100644
index 0000000000..195575f7de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/line-styles/2d.line.width.valid.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.line.width.valid
+// Description:Setting lineWidth to valid values works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Setting lineWidth to valid values works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 1.5;
+ _assertSame(ctx.lineWidth, 1.5, "ctx.lineWidth", "1.5");
+
+ ctx.lineWidth = "1e1";
+ _assertSame(ctx.lineWidth, 10, "ctx.lineWidth", "10");
+
+ ctx.lineWidth = 1/1024;
+ _assertSame(ctx.lineWidth, 1/1024, "ctx.lineWidth", "1/1024");
+
+ ctx.lineWidth = 1000;
+ _assertSame(ctx.lineWidth, 1000, "ctx.lineWidth", "1000");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.html b/testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.html
new file mode 100644
index 0000000000..1cc0e5bffd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-offscreencanvas-converttoblob">
+<script id="myWorker" type="text/worker">
+self.onmessage = function(e) {
+};
+</script>
+<script>
+function makeWorker(script)
+{
+ var blob = new Blob([script]);
+ return new Worker(URL.createObjectURL(blob));
+}
+
+function drawCanvas(ctx)
+{
+ ctx.fillStyle = "red";
+ ctx.fillRect(0, 0, 5, 5);
+ ctx.fillStyle = "green";
+ ctx.fillRect(5, 0, 5, 5);
+ ctx.fillStyle = "blue";
+ ctx.fillRect(0, 5, 5, 5);
+ ctx.fillStyle = "black";
+ ctx.fillRect(5, 5, 5, 5);
+}
+
+function compareImages(image1, image2)
+{
+ var canvas1 = document.createElement('canvas');
+ var canvas2 = document.createElement('canvas');
+ canvas1.width = canvas1.height = 10;
+ canvas2.width = canvas2.height = 10;
+ var ctx1 = canvas1.getContext('2d');
+ var ctx2 = canvas1.getContext('2d');
+ ctx1.drawImage(image1, 0, 0);
+ ctx2.drawImage(image2, 0, 0);
+ var data1 = ctx1.getImageData(0, 0, 10, 10).data;
+ var data2 = ctx2.getImageData(0, 0, 10, 10).data;
+ assert_equals(data1.length, data2.length);
+ var imageMatched = true;
+ for (var i = 0; i < data1.length; i++) {
+ if (data1[i] != data2[i]) {
+ imageMatched = false;
+ break;
+ }
+ }
+ assert_true(imageMatched);
+}
+
+function testConvertToBlob(t, typeVal, qualityVal) {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var oCtx = offscreenCanvas.getContext('2d');
+ drawCanvas(oCtx);
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+ drawCanvas(ctx);
+ var imageLoadedCounter = 0;
+
+ var image1 = new Image();
+ var image2 = new Image();
+ var promise;
+ if (typeVal == "empty" && qualityVal == "empty")
+ promise = offscreenCanvas.convertToBlob();
+ else if (typeVal == "empty" && qualityVal != "empty")
+ promise = offscreenCanvas.convertToBlob({quality: qualityVal});
+ else if (typeVal != "empty" && qualityVal == "empty")
+ promise = offscreenCanvas.convertToBlob({type: typeVal});
+ else
+ promise = offscreenCanvas.convertToBlob({type: typeVal, quality: qualityVal});
+ promise.then(function(blob2) {
+ image2.src = URL.createObjectURL(blob2);
+ if (typeVal == "empty" && qualityVal == "empty") {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ });
+ } else if (typeVal == "empty" && qualityVal != "empty") {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ }, "image/png", qualityVal);
+ } else if (typeVal != "empty" && qualityVal == "empty") {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ }, typeVal, 1.0);
+ } else {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ }, typeVal, qualityVal);
+ }
+ image1.onload = image2.onload = t.step_func(function() {
+ imageLoadedCounter++;
+ if (imageLoadedCounter == 2) {
+ compareImages(image1, image2);
+ t.done();
+ }
+ });
+ });
+}
+
+async_test(function(t) {
+ testConvertToBlob(t, "empty", "empty");
+ testConvertToBlob(t, "empty", 1.0);
+ testConvertToBlob(t, "empty", 0.2);
+}, "Test that convertToBlob with default type produces correct result");
+
+async_test(function(t) {
+ testConvertToBlob(t, "image/png", "empty");
+ testConvertToBlob(t, "image/png", 1.0);
+ testConvertToBlob(t, "image/png", 0.2);
+}, "Test that convertToBlob with png produces correct result");
+
+async_test(function(t) {
+ testConvertToBlob(t, "image/jpeg", "empty");
+ testConvertToBlob(t, "image/jpeg", 1.0);
+ testConvertToBlob(t, "image/jpeg", 0.2);
+}, "Test that convertToBlob with jpge produces correct result");
+
+async_test(function(t) {
+ testConvertToBlob(t, "image/webp", "empty");
+ testConvertToBlob(t, "image/webp", 1.0);
+ testConvertToBlob(t, "image/webp", 0.2);
+}, "Test that convertToBlob with webp produces correct result");
+
+async_test(function(t) {
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
+ offscreenCanvas.convertToBlob().then(t.step_func_done(function() {
+ assert_false("convertToBlob didn't throw, but should be");
+ }), t.step_func_done(function(e) {
+ assert_true(e instanceof DOMException);
+ assert_equals(e.name, "InvalidStateError");
+ }));
+}, "Test that call convertToBlob on a detached OffscreenCanvas throws exception");
+
+async_test(function(t) {
+ var offscreenCanvas = new OffscreenCanvas(0, 0);
+ offscreenCanvas.convertToBlob().then(t.step_func_done(function() {
+ assert_false("convertToBlob didn't throw, but should be");
+ }), t.step_func_done(function(e) {
+ assert_true(e instanceof DOMException);
+ assert_equals(e.name, "IndexSizeError");
+ }));
+}, "Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception");
+
+async_test(function(t) {
+ var img = new Image();
+ img.src = "/images/green.png";
+ img.crossOrigin = "anonymous";
+ img.onload = t.step_func_done(() => {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext("2d");
+ ctx.drawImage(img, 0, 0);
+ offscreenCanvas.convertToBlob().then(t.step_func_done(function() {
+ assert_false("convertToBlob didn't throw, but should");
+ }), t.step_func_done(function(e) {
+ assert_true(e instanceof DOMException);
+ assert_equals(e.name, "SecurityError");
+ }));
+ });
+}, "Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.w.html
new file mode 100644
index 0000000000..5c1fa4cf40
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/convert-to-blob/offscreencanvas.convert.to.blob.w.html
@@ -0,0 +1,337 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-offscreencanvas-converttoblob">
+<script id="myWorker" type="text/worker">
+function drawCanvas(ctx)
+{
+ ctx.fillStyle = "red";
+ ctx.fillRect(0, 0, 5, 5);
+ ctx.fillStyle = "green";
+ ctx.fillRect(5, 0, 5, 5);
+ ctx.fillStyle = "blue";
+ ctx.fillRect(0, 5, 5, 5);
+ ctx.fillStyle = "black";
+ ctx.fillRect(5, 5, 5, 5);
+}
+
+function testConvertToBlob(typeVal, qualityVal) {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var oCtx = offscreenCanvas.getContext('2d');
+ drawCanvas(oCtx);
+
+ var promise;
+ if (typeVal == "empty" && qualityVal == "empty")
+ promise = offscreenCanvas.convertToBlob();
+ else if (typeVal == "empty" && qualityVal != "empty")
+ promise = offscreenCanvas.convertToBlob({quality: qualityVal});
+ else if (typeVal != "empty" && qualityVal == "empty")
+ promise = offscreenCanvas.convertToBlob({type: typeVal});
+ else
+ promise = offscreenCanvas.convertToBlob({type: typeVal, quality: qualityVal});
+ promise.then(function(blob) {
+ self.postMessage(blob);
+ });
+}
+
+function testConvertToBlobException1()
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ self.postMessage({offscreenCanvas}, [offscreenCanvas]);
+ offscreenCanvas.convertToBlob().then(function() {
+ self.postMessage(false);
+ }, function(e) {
+ self.postMessage(e instanceof DOMException && e.name == "InvalidStateError");
+ });
+}
+
+function testConvertToBlobException2()
+{
+ var offscreenCanvas = new OffscreenCanvas(0, 0);
+ offscreenCanvas.convertToBlob().then(function() {
+ self.postMessage(false);
+ }, function(e) {
+ self.postMessage(e instanceof DOMException && e.name == "IndexSizeError");
+ });
+}
+
+function testConvertToBlobException3(bitmap)
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext("2d");
+ ctx.drawImage(bitmap, 0, 0);
+ offscreenCanvas.convertToBlob().then(function() {
+ self.postMessage(false);
+ }, function(e) {
+ self.postMessage(e instanceof DOMException && e.name == "SecurityError");
+ });
+}
+
+self.onmessage = function(e) {
+ if (e.data instanceof ImageBitmap) {
+ testConvertToBlobException3(e.data);
+ return;
+ }
+
+ switch(e.data) {
+ case 'test1':
+ testConvertToBlob("empty", "empty");
+ break;
+ case 'test2':
+ testConvertToBlob("empty", 1.0);
+ break;
+ case 'test3':
+ testConvertToBlob("empty", 0.2);
+ break;
+ case 'test4':
+ testConvertToBlob("image/png", "empty");
+ break;
+ case 'test5':
+ testConvertToBlob("image/png", 1.0);
+ break;
+ case 'test6':
+ testConvertToBlob("image/png", 0.2);
+ break;
+ case 'test7':
+ testConvertToBlob("image/jpeg", "empty");
+ break;
+ case 'test8':
+ testConvertToBlob("image/jpeg", 1.0);
+ break;
+ case 'test9':
+ testConvertToBlob("image/jpeg", 0.2);
+ break;
+ case 'test10':
+ testConvertToBlob("image/webp", "empty");
+ break;
+ case 'test11':
+ testConvertToBlob("image/webp", 1.0);
+ break;
+ case 'test12':
+ testConvertToBlob("image/webp", 0.2);
+ break;
+ case 'test13':
+ testConvertToBlobException1();
+ break;
+ case 'test14':
+ testConvertToBlobException2();
+ break;
+ }
+};
+
+</script>
+
+<script>
+function makeWorker(test) {
+ var blob = new Blob([document.getElementById("myWorker").textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+ worker.onerror = test.unreached_func("error");
+ return worker;
+}
+
+function drawCanvas(ctx)
+{
+ ctx.fillStyle = "red";
+ ctx.fillRect(0, 0, 5, 5);
+ ctx.fillStyle = "green";
+ ctx.fillRect(5, 0, 5, 5);
+ ctx.fillStyle = "blue";
+ ctx.fillRect(0, 5, 5, 5);
+ ctx.fillStyle = "black";
+ ctx.fillRect(5, 5, 5, 5);
+}
+
+function compareImages(image1, image2)
+{
+ var canvas1 = document.createElement('canvas');
+ var canvas2 = document.createElement('canvas');
+ canvas1.width = canvas1.height = 10;
+ canvas2.width = canvas2.height = 10;
+ var ctx1 = canvas1.getContext('2d');
+ var ctx2 = canvas1.getContext('2d');
+ ctx1.drawImage(image1, 0, 0);
+ ctx2.drawImage(image2, 0, 0);
+ var data1 = ctx1.getImageData(0, 0, 10, 10).data;
+ var data2 = ctx2.getImageData(0, 0, 10, 10).data;
+ assert_equals(data1.length, data2.length);
+ var imageMatched = true;
+ for (var i = 0; i < data1.length; i++) {
+ if (data1[i] != data2[i]) {
+ imageMatched = false;
+ break;
+ }
+ }
+ assert_true(imageMatched);
+}
+
+function compareWithToBlob(t, typeVal, qualityVal, blob2)
+{
+ var image1 = new Image();
+ var image2 = new Image();
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+ drawCanvas(ctx);
+ var imageLoadedCounter = 0;
+
+ if (typeVal == "empty" && qualityVal == "empty") {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ });
+ } else if (typeVal == "empty" && qualityVal != "empty") {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ }, "image/png", qualityVal);
+ } else if (typeVal != "empty" && qualityVal == "empty") {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ }, typeVal, 1.0);
+ } else {
+ canvas.toBlob(function(blob1) {
+ image1.src = URL.createObjectURL(blob1);
+ }, typeVal, qualityVal);
+ }
+ image2.src = URL.createObjectURL(blob2);
+ image1.onload = image2.onload = t.step_func(function() {
+ imageLoadedCounter++;
+ if (imageLoadedCounter == 2) {
+ compareImages(image1, image2);
+ t.done();
+ }
+ });
+}
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "empty", "empty", msg.data);
+ }));
+ worker.postMessage('test1');
+}, "Test that convertToBlob with default arguments produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "empty", 1.0, msg.data);
+ }));
+ worker.postMessage('test2');
+}, "Test that convertToBlob with default type/1.0 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "empty", 0.2, msg.data);
+ }));
+ worker.postMessage('test3');
+}, "Test that convertToBlob with default type/0.2 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/png", "empty", msg.data);
+ }));
+ worker.postMessage('test4');
+}, "Test that convertToBlob with png/default quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/png", 1.0, msg.data);
+ }));
+ worker.postMessage('test5');
+}, "Test that convertToBlob with png/1.0 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/png", 0.2, msg.data);
+ }));
+ worker.postMessage('test6');
+}, "Test that convertToBlob with png/0.2 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/jpeg", "empty", msg.data);
+ }));
+ worker.postMessage('test7');
+}, "Test that convertToBlob with jpeg/default quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/jpeg", 1.0, msg.data);
+ }));
+ worker.postMessage('test8');
+}, "Test that convertToBlob with jpeg/1.0 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/jpeg", 0.2, msg.data);
+ }));
+ worker.postMessage('test9');
+}, "Test that convertToBlob with jpeg/0.2 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/webp", "empty", msg.data);
+ }));
+ worker.postMessage('test10');
+}, "Test that convertToBlob with webp/default quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/webp", 1.0, msg.data);
+ }));
+ worker.postMessage('test11');
+}, "Test that convertToBlob with webp/1.0 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func(function(msg) {
+ compareWithToBlob(t, "image/webp", 0.2, msg.data);
+ }));
+ worker.postMessage('test12');
+}, "Test that convertToBlob with webp/0.2 quality produces correct result in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ if (msg.data instanceof Object)
+ return;
+ assert_true(msg.data);
+ t.done();
+ }));
+ worker.postMessage('test13');
+}, "Test that call convertToBlob on a detached OffscreenCanvas throws exception in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ t.done();
+ }));
+ worker.postMessage('test14');
+}, "Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception in a worker");
+
+async_test(function(t) {
+ var img = new Image();
+ img.src = "/images/green.png";
+ img.crossOrigin = "anonymous";
+ img.onload = t.step_func_done(() => {
+ createImageBitmap(img).then(t.step_func_done(bitmap => {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ t.done();
+ }));
+ worker.postMessage(bitmap);
+ }));
+ });
+}, "Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception in a worker");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.html b/testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.html
new file mode 100644
index 0000000000..a5fd7ab066
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<title>OffscreenCanvas test: 2d.text.draw.generic.family</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<script>
+function drawCanvas(ctx, family)
+{
+ ctx.font = '16px ' + family;
+ ctx.fillText(family, 0, 16);
+}
+
+function testDrawGenericFamily(family)
+{
+ let offscreenCanvas = new OffscreenCanvas(88, 24);
+ let oCtx = offscreenCanvas.getContext('2d');
+ drawCanvas(oCtx, family);
+ let canvas = document.createElement('canvas');
+ let ctx = canvas.getContext('2d');
+ drawCanvas(ctx, family);
+
+ let data1 = oCtx.getImageData(0, 0, 88, 24).data;
+ let data2 = ctx.getImageData(0, 0, 88, 24).data;
+ assert_array_equals(data1, data2,
+ "The image data generated by drawing generic font family '" + family +
+ "' should be the same for both OffscreenCanvas and regular canvas");
+}
+
+test(function() {
+ testDrawGenericFamily('sans-serif');
+}, "Test that drawing sans-serif produces the same result between canvas and OffscreenCanvas");
+
+test(function() {
+ testDrawGenericFamily('serif');
+}, "Test that drawing serif produces the same result between canvas and OffscreenCanvas");
+
+test(function() {
+ testDrawGenericFamily('cursive');
+}, "Test that drawing cursive produces the same result between canvas and OffscreenCanvas");
+
+test(function() {
+ testDrawGenericFamily('fantasy');
+}, "Test that drawing fantasy produces the same result between canvas and OffscreenCanvas");
+
+test(function() {
+ testDrawGenericFamily('monospace');
+}, "Test that drawing monospace produces the same result between canvas and OffscreenCanvas");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.w.html
new file mode 100644
index 0000000000..7a88c032ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/draw-generic-family/2d.text.draw.generic.family.w.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<title>OffscreenCanvas test: 2d.text.draw.generic.family.w</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<script id='myWorker' type='text/worker'>
+self.onmessage = function(e) {
+ let oc = new OffscreenCanvas(88, 24);
+ let ctx = oc.getContext('2d');
+ ctx.font = '32px ' + e.data.family;
+ ctx.fillText(e.data.family, 0, 16);
+ self.postMessage(ctx.getImageData(0, 0, 88, 24).data);
+};
+</script>
+<script>
+function testDrawGenericFamily(t, family)
+{
+ let blob = new Blob([document.getElementById('myWorker').textContent]);
+ let worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ let ctx = document.createElement('canvas').getContext('2d');
+ ctx.font = '32px ' + family;
+ ctx.fillText(family, 0, 16);
+ assert_array_equals(ctx.getImageData(0, 0, 88, 24).data, msg.data,
+ "The image data generated by drawing generic font family '" + family +
+ "' should be the same for both OffscreenCanvas and regular canvas");
+ t.done();
+ });
+ worker.postMessage({family: family});
+}
+
+async_test(function(t) {
+ testDrawGenericFamily(t, 'sans-serif');
+}, "Test that drawing sans-serif produces the same result between canvas and OffscreenCanvas in a Worker");
+
+async_test(function(t) {
+ testDrawGenericFamily(t, 'serif');
+}, "Test that drawing serif produces the same result between canvas and OffscreenCanvas in a Worker");
+
+async_test(function(t) {
+ testDrawGenericFamily(t, 'cursive');
+}, "Test that drawing cursive produces the same result between canvas and OffscreenCanvas in a Worker");
+
+async_test(function(t) {
+ testDrawGenericFamily(t, 'fantasy');
+}, "Test that drawing fantasy produces the same result between canvas and OffscreenCanvas in a Worker");
+
+async_test(function(t) {
+ testDrawGenericFamily(t, 'monospace');
+}, "Test that drawing monospace produces the same result between canvas and OffscreenCanvas in a Worker");
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.html b/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.html
new file mode 100644
index 0000000000..25691983f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.html
@@ -0,0 +1,27 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="offscreencanvas.filter.js"></script>
+<script>
+var patternCanvas = createPatternCanvas();
+
+var getOffscreenContextForFilter = function(filter, pattern) {
+ var oc = new OffscreenCanvas(80, 80);
+ var offCtx = oc.getContext('2d');
+ offCtx.filter = filter;
+ offCtx.drawImage(pattern, 5, 5);
+ offCtx.drawImage(pattern, 25, 25);
+ offCtx.drawImage(pattern, 45, 45);
+ return offCtx;
+};
+
+var testFilter = function(filter) {
+ var offCtx = getOffscreenContextForFilter(filter, patternCanvas);
+ var ctx = getRegularContextForFilter(filter, patternCanvas);
+ var offImageData = offCtx.getImageData(0, 0, 80, 80).data;
+ var imageData = ctx.getImageData(0, 0, 80, 80).data;
+ matchImageDataResults(offImageData, imageData, filter);
+};
+
+generate_tests(testFilter, [filters]);
+
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.js b/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.js
new file mode 100644
index 0000000000..cb2e245803
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.js
@@ -0,0 +1,48 @@
+var getRegularContextForFilter = function(filter, pattern) {
+ var c = document.createElement("canvas");
+ c.width = c.height = 80;
+ var ctx = c.getContext('2d');
+ ctx.filter = filter;
+ ctx.drawImage(pattern, 5, 5);
+ ctx.drawImage(pattern, 25, 25);
+ ctx.drawImage(pattern, 45, 45);
+ return ctx;
+};
+
+var matchImageDataResults = function(offscreenImage, regularImage, filter) {
+ assert_array_equals(offscreenImage, regularImage,
+ "The image data generated by filter " +
+ filter +
+ " should be the same for both OffscreenCanvas and regular canvas");
+};
+
+var createPatternCanvas = function() {
+ var patternCanvas = document.createElement('canvas');
+ patternCanvas.width = 20;
+ patternCanvas.height = 20;
+ var patternCtx = patternCanvas.getContext('2d');
+ patternCtx.fillStyle = '#A00';
+ patternCtx.fillRect(0, 0, 10, 10);
+ patternCtx.fillStyle = '#0A0';
+ patternCtx.fillRect(10, 0, 10, 10);
+ patternCtx.fillStyle = '#00A';
+ patternCtx.fillRect(0, 10, 10, 10);
+ patternCtx.fillStyle = "#AA0";
+ patternCtx.fillRect(10, 10, 10, 10);
+ return patternCanvas;
+};
+
+var filters = [ "none" ,
+ "blur(10px)" ,
+ "brightness(40%)" ,
+ "contrast(20%)" ,
+ "drop-shadow(0 0 5px green)" ,
+ "grayscale(100%)" ,
+ "invert(100%)" ,
+ "opacity(50%)" ,
+ "saturate(20%)" ,
+ "sepia(100%)" ,
+ "sepia(1) hue-rotate(200deg)",
+ "url(#url)" ];
+
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.w.html
new file mode 100644
index 0000000000..d6ed915b53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/filter/offscreencanvas.filter.w.html
@@ -0,0 +1,54 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="offscreencanvas.filter.js"></script>
+<script id='myWorker' type='text/worker'>
+self.onmessage = function(e) {
+ var getOffscreenCanvasForFilter = function(filter, pattern) {
+ var oc = new OffscreenCanvas(80, 80);
+ var offCtx = oc.getContext('2d');
+ offCtx.filter = filter;
+ offCtx.drawImage(pattern, 5, 5);
+ offCtx.drawImage(pattern, 25, 25);
+ offCtx.drawImage(pattern, 45, 45);
+ return oc;
+ };
+
+ var filters = e.data.filters;
+ var pattern = e.data.pattern;
+ var ret = [];
+ for (var i = 0; i < filters.length; i++) {
+ var oc = getOffscreenCanvasForFilter(filters[i], pattern);
+ var imageBitmap = oc.transferToImageBitmap();
+ ret.push(imageBitmap);
+ }
+ self.postMessage(ret, ret);
+};
+</script>
+<script>
+var patternCanvas = createPatternCanvas();
+
+// Build a list of image data on regular canvas with different filters
+var listCanvasImageData = [];
+for (var j = 0; j < filters.length; j++) {
+ var ctx = getRegularContextForFilter(filters[j], patternCanvas);
+ listCanvasImageData.push(ctx.getImageData(0, 0, 80, 80).data);
+}
+
+function consumeImageBitmap(patternImage) {
+ async_test(t => {
+ var blob = new Blob([document.getElementById('myWorker').textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ for (var i = 0; i < msg.data.length; ++i) {
+ var outputCtx = document.createElement("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data[i], 0, 0, 80, 80);
+ matchImageDataResults(outputCtx.getImageData(0, 0, 80, 80).data, listCanvasImageData[i], filters[i]);
+ }
+ t.done();
+ });
+ worker.postMessage({filters: filters, pattern: patternImage}, [patternImage]);
+ });
+}
+
+createImageBitmap(patternCanvas).then(consumeImageBitmap);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.html b/testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.html
new file mode 100644
index 0000000000..a78524c51d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OffscreenCanvasRenderingContext2D imageSmoothingEnabled test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#the-offscreen-2d-rendering-context">
+<script>
+function createTestImage() {
+ var image = new OffscreenCanvas(100, 50);
+ var imgctx = image.getContext('2d');
+ imgctx.fillStyle = "#F00";
+ imgctx.fillRect(0, 0, 2, 2);
+ imgctx.fillStyle = "#0F0";
+ imgctx.fillRect(0, 0, 1, 1);
+ return image;
+}
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ assert_true(ctx.imageSmoothingEnabled);
+}, "When the context is created, imageSmoothingEnabled must be set to true.");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.imageSmoothingEnabled = false;
+ assert_false(ctx.imageSmoothingEnabled);
+}, "On getting imageSmoothingEnabled, the user agent must return the last value it was set to.");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_not_equals(pixels[0], 0);
+ assert_not_equals(pixels[1], 255);
+}, "Test that image smoothing is actually on by default.");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.imageSmoothingEnabled = true;
+ var image = createTestImage();
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_not_equals(pixels[0], 0);
+ assert_not_equals(pixels[1], 255);
+}, "Test that image smoothing works when imageSmoothingEnabled is set to true");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with drawImage().");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.fillStyle = ctx.createPattern(image, 'repeat');
+ ctx.fillRect(0, 0, 10, 10);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with fillRect and createPattern().");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.fillStyle = ctx.createPattern(image, 'repeat');
+ ctx.scale(10, 10);
+ ctx.rect(0, 0, 10, 10);
+ ctx.fill();
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with fill() and createPattern().");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.strokeStyle = ctx.createPattern(image, 'repeat');
+ ctx.lineWidth = 5;
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.stroke();
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with stroke() and createPattern().");
+
+test(function() {
+ var repaints = 5;
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+
+ function draw() {
+ ctx.clearRect(0, 0, 10, 10);
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+ }
+
+ while (repaints > 0) {
+ draw();
+ repaints = repaints - 1;
+ }
+
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) still works after repaints.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.worker.js
new file mode 100644
index 0000000000..4c37e84b1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/image-smoothing/image.smoothing.worker.js
@@ -0,0 +1,126 @@
+// spec link: https://html.spec.whatwg.org/#the-offscreen-2d-rendering-context
+
+importScripts("/resources/testharness.js");
+
+function createTestImage() {
+ var image = new OffscreenCanvas(100, 50);
+ var imgctx = image.getContext('2d');
+ imgctx.fillStyle = "#F00";
+ imgctx.fillRect(0, 0, 2, 2);
+ imgctx.fillStyle = "#0F0";
+ imgctx.fillRect(0, 0, 1, 1);
+ return image;
+}
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ assert_true(ctx.imageSmoothingEnabled);
+}, "When the context is created, imageSmoothingEnabled must be set to true.");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.imageSmoothingEnabled = false;
+ assert_false(ctx.imageSmoothingEnabled);
+}, "On getting imageSmoothingEnabled, the user agent must return the last value it was set to.");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_not_equals(pixels[0], 0);
+ assert_not_equals(pixels[1], 255);
+}, "Test that image smoothing is actually on by default.");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.imageSmoothingEnabled = true;
+ var image = createTestImage();
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_not_equals(pixels[0], 0);
+ assert_not_equals(pixels[1], 255);
+}, "Test that image smoothing works when imageSmoothingEnabled is set to true");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with drawImage().");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.fillStyle = ctx.createPattern(image, 'repeat');
+ ctx.fillRect(0, 0, 10, 10);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with fillRect and createPattern().");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.fillStyle = ctx.createPattern(image, 'repeat');
+ ctx.scale(10, 10);
+ ctx.rect(0, 0, 10, 10);
+ ctx.fill();
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with fill() and createPattern().");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ var image = createTestImage();
+ ctx.strokeStyle = ctx.createPattern(image, 'repeat');
+ ctx.lineWidth = 5;
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.stroke();
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) works with stroke() and createPattern().");
+
+test(function() {
+ var repaints = 5;
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+
+ function draw() {
+ ctx.clearRect(0, 0, 10, 10);
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
+ var image = createTestImage();
+ ctx.imageSmoothingEnabled = false;
+ ctx.scale(10, 10);
+ ctx.drawImage(image, 0, 0);
+ var pixels = ctx.getImageData(9, 9, 1, 1).data;
+ assert_array_equals(pixels, [0, 255, 0, 255]);
+ }
+
+ while (repaints > 0) {
+ draw();
+ repaints = repaints - 1;
+ }
+
+}, "Test that imageSmoothingEnabled = false (nearest-neighbor interpolation) still works after repaints.");
+
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers-expected.html b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers-expected.html
new file mode 100644
index 0000000000..873869ea72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Canvas test: unclosed-layers</title>
+<h1>unclosed-layers</h1>
+<p class="desc">Check that unclosed layers aren't rendered.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.html b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.html
new file mode 100644
index 0000000000..4fee600d6c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="match" href="unclosed-layers-expected.html">
+<title>Canvas test: unclosed-layers</title>
+<h1>unclosed-layers</h1>
+<p class="desc">Check that unclosed layers aren't rendered.</p>
+<canvas id="canvas" width="1" height="1">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ var placeholder = document.getElementById('canvas');
+ var offscreen = placeholder.transferControlToOffscreen();
+ const ctx = offscreen.getContext('2d');
+ offscreen.width = offscreen.height = 200;
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}});
+ ctx.fillRect(40, 40, 75, 50);
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(50, 50, 75, 50);
+
+ function draw () {
+ // Wait until frame propagates.
+ if(placeholder.width != 200) {
+ requestAnimationFrame(draw);
+ } else {
+ document.documentElement.classList.remove("reftest-wait");
+ }
+ }
+ requestAnimationFrame(draw);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.w.html
new file mode 100644
index 0000000000..a0014bb597
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-layers.w.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="match" href="unclosed-layers-expected.html">
+<title>Canvas test: unclosed-layers</title>
+<h1>unclosed-layers</h1>
+<p class="desc">Check that unclosed layers aren't rendered.</p>
+<canvas id="canvas" width="1" height="1">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = msg => {
+ const offscreen = msg.data.canvas;
+ const ctx = offscreen.getContext('2d');
+ offscreen.width = offscreen.height = 200;
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}});
+ ctx.fillRect(40, 40, 75, 50);
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(50, 50, 75, 50);
+
+ self.postMessage('setup ready');
+ }
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ var placeholder = document.getElementById('canvas');
+ var offscreen = placeholder.transferControlToOffscreen();
+ worker.addEventListener('message', msg => {
+ if(msg.data == 'setup ready') {
+ function draw () {
+ // Wait until frame propagates.
+ if(placeholder.width != 1) {
+ document.documentElement.classList.remove("reftest-wait");
+ } else {
+ requestAnimationFrame(draw);
+ }
+ }
+ requestAnimationFrame(draw);
+ }
+ });
+ worker.postMessage({
+ canvas: offscreen
+ }, [offscreen]);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers-expected.html b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers-expected.html
new file mode 100644
index 0000000000..8557441f7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Canvas test: unclosed-nested-layers</title>
+<h1>unclosed-nested-layers</h1>
+<p class="desc">Check that unclosed nested layers aren't rendered.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0,0,255,1)';
+ ctx.fillRect(60,60,75,50);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.html b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.html
new file mode 100644
index 0000000000..c6925beb74
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="match" href="unclosed-nested-layers-expected.html">
+<title>Canvas test: unclosed-nested-layers</title>
+<h1>unclosed-nested-layers</h1>
+<p class="desc">Check that unclosed nested layers aren't rendered.</p>
+<canvas id="canvas" width="1" height="1">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ var placeholder = document.getElementById('canvas');
+ var offscreen = placeholder.transferControlToOffscreen();
+ const ctx = offscreen.getContext('2d');
+ offscreen.width = offscreen.height = 200;
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ // Missing ctx.endLayer() here.
+
+ function draw () {
+ // Wait until frame propagates.
+ if(placeholder.width != 200) {
+ requestAnimationFrame(draw);
+ } else {
+ document.documentElement.classList.remove("reftest-wait");
+ }
+ }
+ requestAnimationFrame(draw);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.w.html
new file mode 100644
index 0000000000..1a1dc54052
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/layers/unclosed-nested-layers.w.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="match" href="unclosed-nested-layers-expected.html">
+<title>Canvas test: unclosed-nested-layers</title>
+<h1>unclosed-nested-layers</h1>
+<p class="desc">Check that unclosed nested layers aren't rendered.</p>
+<canvas id="canvas" width="1" height="1">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = msg => {
+ const offscreen = msg.data.canvas;
+ const ctx = offscreen.getContext('2d');
+ offscreen.width = offscreen.height = 200;
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ // Missing ctx.endLayer() here.
+
+ self.postMessage('setup ready');
+ }
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ var placeholder = document.getElementById('canvas');
+ var offscreen = placeholder.transferControlToOffscreen();
+ worker.addEventListener('message', msg => {
+ if(msg.data == 'setup ready') {
+ function draw () {
+ // Wait until frame propagates.
+ if(placeholder.width != 1) {
+ document.documentElement.classList.remove("reftest-wait");
+ } else {
+ requestAnimationFrame(draw);
+ }
+ }
+ requestAnimationFrame(draw);
+ }
+ });
+ worker.postMessage({
+ canvas: offscreen
+ }, [offscreen]);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas-worker-font-load-crash.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas-worker-font-load-crash.html
new file mode 100644
index 0000000000..1baf7847de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas-worker-font-load-crash.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html class="test-wait reftest-wait">
+<script>
+ let url = URL.createObjectURL(new Blob([`
+ let font = new FontFace('Ahem', 'url(/fonts/Ahem.ttf)');
+ self.fonts.add(font);
+ let canvas = new OffscreenCanvas(100, 100);
+ let ctx = canvas.getContext('2d');
+ ctx.font = "10px Ahem";
+ ctx.fillText('Hello', 0, 10);
+ postMessage('done');
+ `], { type: "application/javascript" }));
+ var worker = new Worker(url);
+ worker.onmessage = function() {
+ worker.terminate();
+ URL.revokeObjectURL(url);
+ document.documentElement.className = "";
+ };
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.html
new file mode 100644
index 0000000000..a2ad1dcc7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-offscreencanvas">
+<script>
+
+test(function() {
+ assert_throws_js(
+ TypeError,
+ () => OffscreenCanvas(100, 50),
+ "Calling OffscreenCanvas constructor without 'new' must throw"
+ );
+}, "OffscreenCanvas constructor called as normal function");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ assert_equals(offscreenCanvas.width, 100);
+ assert_equals(offscreenCanvas.height, 50);
+
+ offscreenCanvas.width = 50;
+ offscreenCanvas.height = 100;
+ assert_equals(offscreenCanvas.width, 50);
+ assert_equals(offscreenCanvas.height, 100);
+}, "Test that calling OffscreenCanvas's constructor generates correct width and height.");
+
+test(function() {
+ var offscreenCanvas1 = new OffscreenCanvas(1, 1);
+
+ offscreenCanvas1.width = null;
+ offscreenCanvas1.height = null;
+ assert_equals(offscreenCanvas1.width, 0);
+ assert_equals(offscreenCanvas1.height, 0);
+
+ assert_throws_js(TypeError, function() { new OffscreenCanvas(-1, -1); });
+
+ var offscreenCanvas2 = new OffscreenCanvas(null, null);
+ assert_equals(offscreenCanvas2.width, 0);
+ assert_equals(offscreenCanvas2.height, 0);
+
+ assert_throws_js(TypeError, function() { offscreenCanvas2.width = -1; });
+ assert_throws_js(TypeError, function() { offscreenCanvas2.height = -1; });
+
+ var obj = {Name: "John Doe", Age: 30};
+ assert_throws_js(TypeError, function() { offscreenCanvas2.width = obj; });
+ assert_throws_js(TypeError, function() { offscreenCanvas2.height = obj; });
+ assert_throws_js(TypeError, function() { new OffscreenCanvas(obj, obj); });
+}, "Test that OffscreenCanvas constructor handles invalid arguments correctly");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.worker.js
new file mode 100644
index 0000000000..72cfb728f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.constructor.worker.js
@@ -0,0 +1,45 @@
+// spec link: https://html.spec.whatwg.org/#dom-offscreencanvas
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t1 = async_test("Test that calling OffscreenCanvas's constructor generates correct width and height.");
+t1.step(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ assert_equals(offscreenCanvas.width, 100);
+ assert_equals(offscreenCanvas.height, 50);
+
+ offscreenCanvas.width = 50;
+ offscreenCanvas.height = 100;
+ assert_equals(offscreenCanvas.width, 50);
+ assert_equals(offscreenCanvas.height, 100);
+ t1.done();
+});
+
+var t2 = async_test("Test that OffscreenCanvas constructor handles invalid arguments correctly in a worker");
+t2.step(function() {
+ var offscreenCanvas1 = new OffscreenCanvas(1, 1);
+
+ offscreenCanvas1.width = null;
+ offscreenCanvas1.height = null;
+ assert_equals(offscreenCanvas1.width, 0);
+ assert_equals(offscreenCanvas1.height, 0);
+
+ assert_throws_js(TypeError, function() { new OffscreenCanvas(-1, -1); });
+
+ var offscreenCanvas2 = new OffscreenCanvas(null, null);
+ assert_equals(offscreenCanvas2.width, 0);
+ assert_equals(offscreenCanvas2.height, 0);
+
+ assert_throws_js(TypeError, function() { offscreenCanvas2.width = -1; });
+ assert_throws_js(TypeError, function() { offscreenCanvas2.height = -1; });
+
+ var obj = {Name: "John Doe", Age: 30};
+ assert_throws_js(TypeError, function() { offscreenCanvas2.width = obj; });
+ assert_throws_js(TypeError, function() { offscreenCanvas2.height = obj; });
+ assert_throws_js(TypeError, function() { new OffscreenCanvas(obj, obj); });
+ t2.done();
+});
+
+done();
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.html
new file mode 100644
index 0000000000..51c167ddca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-offscreencanvas-getcontext">
+<script>
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(1, 1);
+ assert_throws_js(TypeError, function() { offscreenCanvas.getContext('3d'); });
+}, "Test that getContext with un-supported string throws a TypeError.");
+
+test(function() {
+ var offscreenCanvas1 = new OffscreenCanvas(1, 1);
+ var ctx1 = offscreenCanvas1.getContext('2d');
+ assert_true(ctx1 instanceof OffscreenCanvasRenderingContext2D);
+
+ var offscreenCanvas2 = new OffscreenCanvas(1, 1);
+ var ctx2 = offscreenCanvas2.getContext('webgl');
+ assert_true(ctx2 instanceof WebGLRenderingContext);
+
+ var offscreenCanvas3 = new OffscreenCanvas(1, 1);
+ var ctx3 = offscreenCanvas3.getContext('webgl2');
+ assert_true(ctx3 instanceof WebGL2RenderingContext);
+}, "Test that getContext with supported string returns correct results");
+
+test(function() {
+ var offscreenCanvas1 = new OffscreenCanvas(1, 1);
+ var ctx1 = offscreenCanvas1.getContext('2d');
+ var ctx2 = offscreenCanvas1.getContext('webgl');
+ assert_equals(ctx2, null);
+
+ var offscreenCanvas2 = new OffscreenCanvas(1, 1);
+ var ctx3 = offscreenCanvas2.getContext('webgl');
+ var ctx4 = offscreenCanvas2.getContext('2d');
+ assert_equals(ctx4, null);
+}, "Test that getContext twice with different context type returns null the second time");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(1, 2);
+ var ctx = offscreenCanvas.getContext('2d');
+ var dstCanvas = ctx.canvas;
+ assert_equals(dstCanvas.width, 1);
+ assert_equals(dstCanvas.height, 2);
+}, "Test that 2dcontext.canvas should return the original OffscreenCanvas");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(1, 2);
+ var ctx = offscreenCanvas.getContext('webgl');
+ var dstCanvas = ctx.canvas;
+ assert_equals(dstCanvas.width, 1);
+ assert_equals(dstCanvas.height, 2);
+}, "Test that webglcontext.canvas should return the original OffscreenCanvas");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('2d', {alpha: false});
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(offscreenCanvas, 5,5, 0,127,0,255, 2);
+}, "Test that OffscreenCanvasRenderingContext2D with alpha disabled makes the OffscreenCanvas opaque");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('2d', {alpha: true});
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(offscreenCanvas, 5,5, 0,255,0,127, 2);
+}, "Test that OffscreenCanvasRenderingContext2D with alpha enabled preserves the alpha");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(offscreenCanvas, 5,5, 0,255,0,127, 2);
+}, "Test that 'alpha' context creation attribute is true by default");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.worker.js b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.worker.js
new file mode 100644
index 0000000000..c413791f61
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.worker.js
@@ -0,0 +1,77 @@
+// spec link: https://html.spec.whatwg.org/#dom-offscreencanvas-getcontext
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(1, 1);
+ assert_throws_js(TypeError, function() { offscreenCanvas.getContext('3d'); });
+}, "Test that getContext with un-supported string throws a TypeError.");
+
+test(function() {
+ var offscreenCanvas1 = new OffscreenCanvas(1, 1);
+ var ctx1 = offscreenCanvas1.getContext('2d');
+ assert_true(ctx1 instanceof OffscreenCanvasRenderingContext2D);
+
+ var offscreenCanvas2 = new OffscreenCanvas(1, 1);
+ var ctx2 = offscreenCanvas2.getContext('webgl');
+ assert_true(ctx2 instanceof WebGLRenderingContext);
+
+ var offscreenCanvas3 = new OffscreenCanvas(1, 1);
+ var ctx3 = offscreenCanvas3.getContext('webgl2');
+ assert_true(ctx3 instanceof WebGL2RenderingContext);
+}, "Test that getContext with supported string returns correct results");
+
+test(function() {
+ var offscreenCanvas1 = new OffscreenCanvas(1, 1);
+ var ctx1 = offscreenCanvas1.getContext('2d');
+ var ctx2 = offscreenCanvas1.getContext('webgl');
+ assert_equals(ctx2, null);
+
+ var offscreenCanvas2 = new OffscreenCanvas(1, 1);
+ var ctx3 = offscreenCanvas2.getContext('webgl');
+ var ctx4 = offscreenCanvas2.getContext('2d');
+ assert_equals(ctx4, null);
+}, "Test that getContext twice with different context type returns null the second time");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(1, 2);
+ var ctx = offscreenCanvas.getContext('2d');
+ var dstCanvas = ctx.canvas;
+ assert_equals(dstCanvas.width, 1);
+ assert_equals(dstCanvas.height, 2);
+}, "Test that 2dcontext.canvas should return the original OffscreenCanvas");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(1, 2);
+ var ctx = offscreenCanvas.getContext('webgl');
+ var dstCanvas = ctx.canvas;
+ assert_equals(dstCanvas.width, 1);
+ assert_equals(dstCanvas.height, 2);
+}, "Test that webglcontext.canvas should return the original OffscreenCanvas");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('2d', {alpha: false});
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(offscreenCanvas, 5,5, 0,127,0,255, 2);
+}, "Test that OffscreenCanvasRenderingContext2D with alpha disabled makes the OffscreenCanvas opaque");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('2d', {alpha: true});
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(offscreenCanvas, 5,5, 0,255,0,127, 2);
+}, "Test that OffscreenCanvasRenderingContext2D with alpha enabled preserves the alpha");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(offscreenCanvas, 5,5, 0,255,0,127, 2);
+}, "Test that 'alpha' context creation attribute is true by default");
+
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.resize.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.resize.html
new file mode 100644
index 0000000000..3ff0eea153
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.resize.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<title>Test resizing an OffscreenCanvas with a 2d context</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<body></body>
+<script>
+test(function() {
+ var canvas = new OffscreenCanvas(10, 20);
+ canvas.width = 30;
+ canvas.height = 40;
+ assert_equals(canvas.width, 30);
+ assert_equals(canvas.height, 40);
+}, "Verify that writing to the width and height attributes of an OffscreenCanvas works when there is no context attached.");
+
+test(function() {
+ var canvas = new OffscreenCanvas(10, 20);
+ canvas.getContext('2d');
+ canvas.width = 30;
+ canvas.height = 40;
+ assert_equals(canvas.width, 30);
+ assert_equals(canvas.height, 40);
+ var image = canvas.transferToImageBitmap();
+ assert_equals(image.width, 30);
+ assert_equals(image.height, 40);
+}, "Verify that writing to the width and height attributes of an OffscreenCanvas works when there is a 2d context attached.");
+
+test(function() {
+ var canvas = new OffscreenCanvas(10, 20);
+ canvas.getContext('webgl');
+ canvas.width = 30;
+ canvas.height = 40;
+ assert_equals(canvas.width, 30);
+ assert_equals(canvas.height, 40);
+ var image = canvas.transferToImageBitmap();
+ assert_equals(image.width, 30);
+ assert_equals(image.height, 40);
+}, "Verify that writing to the width and height attributes of an OffscreenCanvas works when there is a webgl context attached.");
+
+test(function() {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 2;
+ placeholder.height = 2;
+ var offscreen = placeholder.transferControlToOffscreen();
+ assert_throws_dom("InvalidStateError", () => { placeholder.width = 1; });
+ assert_throws_dom("InvalidStateError", () => { placeholder.height = 1; });
+}, "Verify that writing to the width or height attribute of a placeholder canvas throws an exception");
+
+test(function() {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 1;
+ placeholder.height = 1;
+ var offscreen = placeholder.transferControlToOffscreen();
+ assert_throws_dom("InvalidStateError", () => { placeholder.width = 1; });
+ assert_throws_dom("InvalidStateError", () => { placeholder.height = 1; });
+}, "Verify that writing to the width or height attribute of a placeholder canvas throws an exception even when not changing the value of the attribute.");
+
+test(function() {
+ var canvas = new OffscreenCanvas(10, 20);
+ var ctx = canvas.getContext('2d');
+ ctx.lineWidth = 5;
+ canvas.width = 30;
+ assert_equals(ctx.lineWidth, 1);
+ ctx.lineWidth = 5;
+ canvas.height = 40;
+ assert_equals(ctx.lineWidth, 1);
+}, "Verify that resizing a 2d context resets its state.");
+
+test(function() {
+ var canvas = new OffscreenCanvas(10, 20);
+ var ctx = canvas.getContext('2d');
+ ctx.lineWidth = 5;
+ canvas.width = canvas.width;
+ assert_equals(ctx.lineWidth, 1);
+ ctx.lineWidth = 5;
+ canvas.height = canvas.height;
+ assert_equals(ctx.lineWidth, 1);
+}, "Verify that setting the size of a 2d context to the same size it already had resets its state.");
+
+async_test(function(t) {
+ var placeholder = document.createElement('canvas');
+ document.body.appendChild(placeholder); // So that we can check computed style/
+ placeholder.width = 10;
+ placeholder.height = 20;
+ var offscreen = placeholder.transferControlToOffscreen();
+ var ctx = offscreen.getContext('2d');
+ t.step(function() {
+ // Verify that setting the size of an OffscreenCanvas that has a placeholder works.
+ offscreen.width = 30;
+ offscreen.height = 40;
+ assert_equals(offscreen.width, 30);
+ assert_equals(offscreen.height, 40);
+ var image = offscreen.transferToImageBitmap();
+ assert_equals(image.width, 30);
+ assert_equals(image.height, 40);
+ });
+ t.step(function() {
+ // Verify that setting the size of an OffscreenCanvas does not directly update the size of its placeholder canvas.
+ assert_equals(placeholder.width, 10);
+ assert_equals(placeholder.height, 20);
+ });
+ var asyncStepsCompleted = 0;
+ createImageBitmap(placeholder).then(image => {
+ t.step(function() {
+ // Verify that the placeholder was not updated synchronously.
+ assert_equals(image.width, 10);
+ assert_equals(image.height, 20);
+ });
+ asyncStepsCompleted = asyncStepsCompleted + 1;
+ if (asyncStepsCompleted == 2) {
+ t.done();
+ }
+ });
+
+ function testImage() {
+ if (placeholder.width != 30) {
+ requestAnimationFrame(testImage);
+ } else {
+ t.step(function() {
+ assert_equals(placeholder.width, 30);
+ assert_equals(placeholder.height, 40);
+ var computedStyle = window.getComputedStyle(placeholder);
+ assert_equals(computedStyle.getPropertyValue('width'), "30px");
+ assert_equals(computedStyle.getPropertyValue('height'), "40px");
+ });
+ createImageBitmap(placeholder).then(image => {
+ t.step(function() {
+ // Verify that an image grabbed from the placeholder has the correct dimensions
+ assert_equals(image.width, 30);
+ assert_equals(image.height, 40);
+ });
+ asyncStepsCompleted = asyncStepsCompleted + 1;
+ if (asyncStepsCompleted == 2) {
+ t.done();
+ }
+ });
+ }
+ }
+
+ requestAnimationFrame(testImage);
+}, "Verify that resizing an OffscreenCanvas with a 2d context propagates the new size to its placeholder canvas asynchronously.");
+
+async_test(function(t) {
+ var placeholder = document.createElement('canvas');
+ document.body.appendChild(placeholder); // So that we can check computed style/
+ placeholder.width = 10;
+ placeholder.height = 20;
+ var offscreen = placeholder.transferControlToOffscreen();
+ var ctx = offscreen.getContext('webgl');
+ t.step(function() {
+ // Verify that setting the size of an OffscreenCanvas that has a placeholder works.
+ offscreen.width = 30;
+ offscreen.height = 40;
+ assert_equals(offscreen.width, 30);
+ assert_equals(offscreen.height, 40);
+ var image = offscreen.transferToImageBitmap();
+ assert_equals(image.width, 30);
+ assert_equals(image.height, 40);
+ });
+ t.step(function() {
+ // Verify that setting the size of an OffscreenCanvas does not directly update the size of its placeholder canvas.
+ assert_equals(placeholder.width, 10);
+ assert_equals(placeholder.height, 20);
+ });
+ var asyncStepsCompleted = 0;
+ createImageBitmap(placeholder).then(image => {
+ t.step(function() {
+ // Verify that the placeholder was not updated synchronously.
+ assert_equals(image.width, 10);
+ assert_equals(image.height, 20);
+ });
+ asyncStepsCompleted = asyncStepsCompleted + 1;
+ if (asyncStepsCompleted == 2) {
+ t.done();
+ }
+ });
+
+ function testImage() {
+ if (placeholder.width != 30) {
+ requestAnimationFrame(testImage);
+ } else {
+ t.step(function() {
+ assert_equals(placeholder.width, 30);
+ assert_equals(placeholder.height, 40);
+ var computedStyle = window.getComputedStyle(placeholder);
+ assert_equals(computedStyle.getPropertyValue('width'), "30px");
+ assert_equals(computedStyle.getPropertyValue('height'), "40px");
+ });
+ createImageBitmap(placeholder).then(image => {
+ t.step(function() {
+ // Verify that an image grabbed from the placeholder has the correct dimensions
+ assert_equals(image.width, 30);
+ assert_equals(image.height, 40);
+ });
+ asyncStepsCompleted = asyncStepsCompleted + 1;
+ if (asyncStepsCompleted == 2) {
+ t.done();
+ }
+ });
+ }
+ }
+ requestAnimationFrame(testImage);
+}, "Verify that resizing an OffscreenCanvas with a webgl context propagates the new size to its placeholder canvas asynchronously.");
+
+async_test(function(t){
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 1;
+ placeholder.height = 1;
+ var offscreen = placeholder.transferControlToOffscreen();
+ var ctx = offscreen.getContext('2d');
+ offscreen.width = offscreen.height = 10;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 10, 10);
+
+ var testCanvas = document.createElement('canvas');
+ testCanvas.width = testCanvas.height = 20;
+ var testCtx = testCanvas.getContext('2d');
+
+ function testImage() {
+ if (placeholder.width != 10) {
+ requestAnimationFrame(testImage);
+ } else {
+ testCtx.drawImage(placeholder, 0, 0);
+ var pixel1 = testCtx.getImageData(9, 9, 1, 1).data;
+ var pixel2 = testCtx.getImageData(9, 10, 1, 1).data;
+ var pixel3 = testCtx.getImageData(10, 9, 1, 1).data;
+ t.step(function() {
+ assert_equals(placeholder.width, 10);
+ assert_equals(placeholder.height, 10);
+ assert_array_equals(pixel1, [0, 255, 0, 255]);
+ assert_array_equals(pixel2, [0, 0, 0, 0]);
+ assert_array_equals(pixel3, [0, 0, 0, 0]);
+ });
+ t.done();
+ }
+ }
+
+ requestAnimationFrame(testImage);
+}, "Verify that drawImage uses the size of the frame as the intinsic size of a placeholder canvas.");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.lowlatency.nocrash.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.lowlatency.nocrash.html
new file mode 100644
index 0000000000..1960841564
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.lowlatency.nocrash.html
@@ -0,0 +1,12 @@
+<title>Transfer Low-Latency Canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<body></body>
+
+<script>
+test(function(t) {
+ var ctx = document.createElement("canvas").getContext('2d', {desynchronized:true});
+ assert_throws_dom("InvalidStateError", () => { ctx.canvas.transferControlToOffscreen(); });
+}, "Tests that transferring a low latency canvas does not cause a crash. See crbug.com/1255153");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.html
new file mode 100644
index 0000000000..6e1adf9591
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-offscreencanvas-transfertoimagebitmap">
+
+<script id="myWorker" type="text/worker">
+
+self.onmessage = function(e) {
+};
+
+</script>
+
+<script>
+function makeWorker(script)
+{
+ var blob = new Blob([script]);
+ return new Worker(URL.createObjectURL(blob));
+}
+
+test(function() {
+ function testSize(contextType) {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext(contextType);
+ var image = offscreenCanvas.transferToImageBitmap();
+ assert_equals(image.width, 100);
+ assert_equals(image.height, 50);
+ }
+
+ testSize('2d');
+ testSize('webgl');
+}, "Test that transferToImageBitmap returns an ImageBitmap with correct width and height");
+
+test(function() {
+ function testImageBitmapClr(shouldCallTwice, alphaVal) {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d', {alpha: alphaVal});
+ ctx.fillStyle = "#0f0";
+ ctx.fillRect(0, 0, 100, 50);
+ var image = offscreenCanvas.transferToImageBitmap();
+
+ if (shouldCallTwice)
+ image = offscreenCanvas.transferToImageBitmap();
+
+ var drawCanvas = document.createElement('canvas');
+ drawCanvas.width = 100;
+ drawCanvas.height = 50;
+ var dCtx = drawCanvas.getContext('2d');
+ dCtx.drawImage(image, 0, 0);
+
+ if (shouldCallTwice) {
+ if (alphaVal)
+ _assertPixel(drawCanvas, 50,25, 0,0,0,0);
+ else
+ _assertPixel(drawCanvas, 50,25, 0,0,0,255);
+ } else {
+ _assertPixel(drawCanvas, 50,25, 0,255,0,255);
+ }
+ }
+
+ testImageBitmapClr(false, true);
+ testImageBitmapClr(true, true);
+ testImageBitmapClr(true, false);
+}, "Test that transferToImageBitmap returns an ImageBitmap with correct color");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.lineWidth = 10;
+ var image = offscreenCanvas.transferToImageBitmap();
+ assert_equals(ctx.lineWidth, 10);
+}, "Test that transferToImageBitmap won't change context's property");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.rect(0, 0, 25, 50);
+ ctx.clip();
+ ctx.translate(20, 20);
+
+ ctx.fillStyle = '#0f0';
+ var image1 = offscreenCanvas.transferToImageBitmap();
+ // trasnform should be preserved
+ ctx.fillRect(0, 0, 10, 10);
+ var image2 = offscreenCanvas.transferToImageBitmap();
+
+ var drawCanvas = document.createElement('canvas');
+ drawCanvas.width = 100;
+ drawCanvas.height = 50;
+ var dCtx = drawCanvas.getContext('2d');
+ dCtx.drawImage(image2, 0, 0);
+ // Verify that transform was carried over.
+ _assertPixel(drawCanvas, 23,25, 0,255,0,255);
+ // Verify that clip was carried over.
+ _assertPixel(drawCanvas, 27,25, 0,0,0,0);
+}, "Test that transferToImageBitmap preserves transform");
+
+async_test(function(t) {
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ worker.postMessage(offscreenCanvas, [offscreenCanvas]);
+ assert_throws_dom("InvalidStateError", function() { offscreenCanvas.transferToImageBitmap(); });
+ t.done();
+}, "Test that call transferToImageBitmap on a detached OffscreenCanvas throws an exception");
+
+test(function() {
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ assert_throws_dom("InvalidStateError", function() { offscreenCanvas.transferToImageBitmap(); });
+}, "Test that transferToImageBitmap without a context throws an exception");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.nocrash.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.nocrash.html
new file mode 100644
index 0000000000..09a388ed35
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.nocrash.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<body>
+ <p>Tests that an ImageBitmap in Offscreen without content does not crash.</p>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+async_test(function(t) {
+ var v1 = document.createElement("canvas");
+ var v2 = v1.transferControlToOffscreen();
+ var v3 = v2.getContext("bitmaprenderer");
+ v2.width = 67;
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w.html
new file mode 100644
index 0000000000..b51ce0efa2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w.html
@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-offscreencanvas-transfertoimagebitmap">
+
+<script id="myWorker" type="text/worker">
+
+function testSize(contextType)
+{
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext(contextType);
+ var image = offscreenCanvas.transferToImageBitmap();
+ if (image.width == 100 && image.height == 50)
+ return true;
+ return false;
+}
+
+function testImageBitmapClr(shouldCallTwice, alphaVal) {
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d', {alpha: alphaVal});
+ ctx.fillStyle = "#0f0";
+ ctx.fillRect(0, 0, 100, 50);
+ var image = offscreenCanvas.transferToImageBitmap();
+
+ if (shouldCallTwice)
+ image = offscreenCanvas.transferToImageBitmap();
+ return image;
+}
+
+function isInvalidStateError(funcStr, offscreenCanvas)
+{
+ try {
+ eval(funcStr);
+ } catch (e) {
+ if (e instanceof DOMException && e.name == "InvalidStateError")
+ return true;
+ return false;
+ }
+}
+
+function testImageBitmapSize()
+{
+ return testSize('2d') && testSize('webgl');
+}
+
+function testLineWidthNotAltered()
+{
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.lineWidth = 10;
+ var image = offscreenCanvas.transferToImageBitmap();
+ return ctx.lineWidth == 10;
+}
+
+function testTransformPreserved()
+{
+ var offscreenCanvas = new OffscreenCanvas(100, 50);
+ var ctx = offscreenCanvas.getContext('2d');
+ ctx.rect(0, 0, 25, 50);
+ ctx.clip();
+ ctx.translate(20, 20);
+
+ ctx.fillStyle = '#0f0';
+ var image1 = offscreenCanvas.transferToImageBitmap();
+ // trasnform should be preserved
+ ctx.fillRect(0, 0, 10, 10);
+ var image2 = offscreenCanvas.transferToImageBitmap();
+ return image2;
+}
+
+function testException()
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ return isInvalidStateError("offscreenCanvas.transferToImageBitmap()", offscreenCanvas);
+}
+
+self.onmessage = function(e) {
+ switch (e.data) {
+ case 'test1':
+ self.postMessage(testImageBitmapSize());
+ break;
+ case 'test2':
+ self.postMessage(testImageBitmapClr(false, true));
+ break;
+ case 'test3':
+ self.postMessage(testImageBitmapClr(true, true));
+ break;
+ case 'test4':
+ self.postMessage(testImageBitmapClr(true, false));
+ break;
+ case 'test5':
+ self.postMessage(testLineWidthNotAltered());
+ break;
+ case 'test6':
+ self.postMessage(testTransformPreserved());
+ break;
+ case 'test7':
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ self.postMessage({offscreenCanvas: offscreenCanvas}, [offscreenCanvas]);
+ self.postMessage(isInvalidStateError("offscreenCanvas.transferToImageBitmap()", offscreenCanvas));
+ break;
+ case 'test8':
+ self.postMessage(testException());
+ break;
+ }
+};
+
+</script>
+
+<script>
+function makeWorker(test) {
+ var blob = new Blob([document.getElementById("myWorker").textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+ worker.onerror = test.unreached_func("error");
+ return worker;
+}
+
+function drawImageBitmap(image, x, y)
+{
+ var drawCanvas = document.createElement('canvas');
+ drawCanvas.width = 100;
+ drawCanvas.height = 50;
+ var dCtx = drawCanvas.getContext('2d');
+ dCtx.drawImage(image, 0, 0);
+ return dCtx.getImageData(x, y, 1, 1).data;
+}
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test1');
+}, "Test that transferToImageBitmap returns an ImageBitmap with correct width and height in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ var clr = drawImageBitmap(msg.data, 50, 25);
+ assert_array_equals(clr, [0, 255, 0, 255]);
+ }));
+ worker.postMessage('test2');
+}, "Test that transferToImageBitmap returns an ImageBitmap with correct color in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ var clr = drawImageBitmap(msg.data, 50, 25);
+ assert_array_equals(clr, [0, 0, 0, 0]);
+ }));
+ worker.postMessage('test3');
+}, "Test that call transferToImageBitmap twice returns an ImageBitmap with correct color in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ var clr = drawImageBitmap(msg.data, 50, 25);
+ assert_array_equals(clr, [0, 0, 0, 255]);
+ }));
+ worker.postMessage('test4');
+}, "Test that call transferToImageBitmap twice on a alpha-disabled context returns an ImageBitmap with correct color in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test5');
+}, "Test that transferToImageBitmap won't change context's property in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ var clr1 = drawImageBitmap(msg.data, 23, 25);
+ assert_array_equals(clr1, [0, 255, 0, 255]);
+ var clr2 = drawImageBitmap(msg.data, 27, 25);
+ assert_array_equals(clr2, [0, 0, 0, 0]);
+ }));
+ worker.postMessage('test6');
+}, "Test that call transferToImageBitmap preserves transform in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ if (msg.data == true || msg.data == false)
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test7');
+}, "Test that call transferToImageBitmap on a detached OffscreenCanvas throws an exception in a worker");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test8');
+}, "Test that call transferToImageBitmap without a context throws an exception in a worker");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.html
new file mode 100644
index 0000000000..fea375b2ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-canvas-transfercontroltooffscreen">
+<script>
+
+test(function() {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 100;
+ placeholder.height = 50;
+ var offscreenCanvas = placeholder.transferControlToOffscreen();
+ assert_equals(offscreenCanvas.width, 100);
+ assert_equals(offscreenCanvas.height, 50);
+}, "Test that an OffscreenCanvas generated by transferControlToOffscreen gets correct width and height");
+
+test(function() {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 100;
+ placeholder.height = 50;
+ var offscreenCanvas = placeholder.transferControlToOffscreen();
+ assert_throws_dom("InvalidStateError", function() { placeholder.getContext('2d'); });
+}, "Test that calling getContext on a placeholder canvas that has already transferred its control throws an exception");
+
+test(function() {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 100;
+ placeholder.height = 50;
+ var offscreenCanvas = placeholder.transferControlToOffscreen();
+ assert_throws_dom("InvalidStateError", function() { placeholder.transferControlToOffscreen(); });
+}, "Test that calling transferControlToOffscreen twice throws an exception");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w.html
new file mode 100644
index 0000000000..1347e7b50b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfercontrol.to.offscreen.w.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#dom-canvas-transfercontroltooffscreen">
+
+<script id="myWorker" type="text/worker">
+
+function testSize(offscreenCanvas)
+{
+ if (offscreenCanvas.width == 100 && offscreenCanvas.height == 50)
+ return true;
+ return false;
+}
+
+self.onmessage = function(e) {
+ switch (e.data.msg) {
+ case 'test1':
+ self.postMessage(testSize(e.data.data));
+ break;
+ case 'test2':
+ self.postMessage("");
+ break;
+ case 'test3':
+ self.postMessage("");
+ break;
+ }
+};
+
+</script>
+
+<script>
+function makeWorker(script)
+{
+ var blob = new Blob([script]);
+ return new Worker(URL.createObjectURL(blob));
+}
+
+async_test(function(t) {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 100;
+ placeholder.height = 50;
+ var offscreenCanvas = placeholder.transferControlToOffscreen();
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ }));
+ worker.postMessage({msg: 'test1', data: offscreenCanvas}, [offscreenCanvas]);
+}, "Test that an OffscreenCanvas generated by transferControlToOffscreen gets correct width and height when it is transferred to a worker");
+
+async_test(function(t) {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 100;
+ placeholder.height = 50;
+ var offscreenCanvas = placeholder.transferControlToOffscreen();
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_throws_dom("InvalidStateError", function() { placeholder.getContext('2d'); });
+ }));
+ worker.postMessage({msg: 'test2', data: offscreenCanvas}, [offscreenCanvas]);
+}, "Test that calling getContext on a placeholder canvas that is transferred its control to an OffscreenCanvas throws an exception, when the OffscreenCanvas is transferred to a worker");
+
+async_test(function(t) {
+ var placeholder = document.createElement('canvas');
+ placeholder.width = 100;
+ placeholder.height = 50;
+ var offscreenCanvas = placeholder.transferControlToOffscreen();
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_throws_dom("InvalidStateError", function() { placeholder.transferControlToOffscreen(); });
+ }));
+ worker.postMessage({msg: 'test3', data: offscreenCanvas}, [offscreenCanvas]);
+}, "Test that calling transferControlToOffscreen twice throws an exception, when its associated OffscreenCanvas is transferred to a worker");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.html
new file mode 100644
index 0000000000..76796034e9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#offscreencanvas">
+
+<script id="myWorker" type="text/worker">
+
+function test1(offscreenCanvas)
+{
+ return offscreenCanvas.width == 10 && offscreenCanvas.height == 10;
+}
+
+self.onmessage = function(e) {
+ switch(e.data.msg) {
+ case 'test1':
+ self.postMessage(test1(e.data.data));
+ break;
+ }
+};
+
+</script>
+
+<script>
+function makeWorker(script)
+{
+ var blob = new Blob([script]);
+ return new Worker(URL.createObjectURL(blob));
+}
+
+async_test(function(t) {
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ worker.postMessage({msg: 'test1', data: offscreenCanvas}, [offscreenCanvas]);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ }));
+ assert_equals(offscreenCanvas.width, 0);
+ assert_equals(offscreenCanvas.height, 0);
+}, "Test that offscreenCanvas's size is correct after being transferred to a worker.");
+
+
+test(function() {
+ function testException(contextType) {
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext(contextType);
+ assert_throws_dom("InvalidStateError", function() {
+ worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
+ });
+ }
+ testException('2d');
+}, "Test that transfer an OffscreenCanvas that already have a 2d context throws exception.");
+
+test(function() {
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
+ assert_throws_dom("DataCloneError", function() {
+ worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
+ });
+}, "Test that transfer an OffscreenCanvas twice throws exception.");
+
+test(function() {
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
+ assert_throws_dom("InvalidStateError", function() {
+ offscreenCanvas.getContext('2d');
+ });
+}, "Test that calling getContext('2d') on a detached OffscreenCanvas throws exception.");
+
+test(function() {
+ var worker = makeWorker(document.getElementById("myWorker").textContent);
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
+ assert_throws_dom("InvalidStateError", function() {
+ offscreenCanvas.getContext('webgl');
+ });
+}, "Test that calling getContext('webgl') on a detached OffscreenCanvas throws exception.");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.w.html b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.w.html
new file mode 100644
index 0000000000..38f981e8f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.w.html
@@ -0,0 +1,142 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#offscreencanvas">
+
+<script id="myWorker" type="text/worker">
+
+function isInvalidStateError(funcStr, offscreenCanvas)
+{
+ try {
+ eval(funcStr);
+ } catch (e) {
+ if (e instanceof DOMException && e.name == "InvalidStateError")
+ return true;
+ return false;
+ }
+}
+
+function testExceptionWith2DContext()
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('2d');
+ return isInvalidStateError("self.postMessage(offscreenCanvas, [offscreenCanvas])", offscreenCanvas);
+}
+
+function testExceptionWithWebGLContext()
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ var ctx = offscreenCanvas.getContext('webgl');
+ return isInvalidStateError("self.postMessage(offscreenCanvas, [offscreenCanvas])", offscreenCanvas);
+}
+
+function testExceptionWithDetachedOffscreenCanvas1()
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ self.postMessage(offscreenCanvas, [offscreenCanvas]);
+ return isInvalidStateError("self.postMessage(offscreenCanvas, [offscreenCanvas])", offscreenCanvas);
+}
+
+function testExceptionWithDetachedOffscreenCanvas2()
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ self.postMessage(offscreenCanvas, [offscreenCanvas]);
+ return isInvalidStateError("offscreenCanvas.getContext('2d')", offscreenCanvas);
+}
+
+function testExceptionWithDetachedOffscreenCanvas3()
+{
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ self.postMessage(offscreenCanvas, [offscreenCanvas]);
+ return isInvalidStateError("offscreenCanvas.getContext('webgl')", offscreenCanvas);
+}
+
+self.onmessage = function(e) {
+ switch(e.data) {
+ case 'test1':
+ var offscreenCanvas = new OffscreenCanvas(10, 10);
+ self.postMessage(offscreenCanvas, [offscreenCanvas]);
+ break;
+ case 'test2':
+ self.postMessage(testExceptionWith2DContext());
+ break;
+ case 'test3':
+ self.postMessage(testExceptionWithWebGLContext());
+ break;
+ case 'test4':
+ self.postMessage(testExceptionWithDetachedOffscreenCanvas1());
+ break;
+ case 'test5':
+ self.postMessage(testExceptionWithDetachedOffscreenCanvas2());
+ break;
+ case 'test6':
+ self.postMessage(testExceptionWithDetachedOffscreenCanvas3());
+ break;
+ }
+};
+
+</script>
+
+<script>
+function makeWorker(test) {
+ var blob = new Blob([document.getElementById("myWorker").textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+ worker.onerror = test.unreached_func("error");
+ return worker;
+}
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_equals(msg.data.width, 10);
+ assert_equals(msg.data.height, 10);
+ }));
+ worker.postMessage('test1');
+}, "Test that OffscreenCanvas's size is correct after being transferred from a worker.");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test2');
+}, "Test that transfer an OffscreenCanvas that has a 2d context throws exception in a worker.");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test3');
+}, "Test that transfer an OffscreenCanvas that has a webgl context throws exception in a worker.");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ if (msg.data == true || msg.data == false)
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test4');
+}, "Test that transfer an OffscreenCanvas twice throws exception in a worker.");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ if (msg.data == true || msg.data == false)
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test5');
+}, "Test that calling getContext('2d') on a detached OffscreenCanvas throws exception in a worker.");
+
+async_test(function(t) {
+ var worker = makeWorker(t);
+ worker.addEventListener('message', t.step_func_done(function(msg) {
+ if (msg.data == true || msg.data == false)
+ assert_true(msg.data);
+ }));
+ worker.postMessage('test6');
+}, "Test that calling getContext('webgl') on a detached OffscreenCanvas throws exception in a worker.");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/transformations/2d.transformation.getTransform.html b/testing/web-platform/tests/html/canvas/offscreen/manual/transformations/2d.transformation.getTransform.html
new file mode 100644
index 0000000000..b3b70ac208
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/transformations/2d.transformation.getTransform.html
@@ -0,0 +1,40 @@
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+// Ensure that context2d.getTransform works
+const epsilon = 1e-5;
+const canvas = new OffscreenCanvas(300, 150);
+const ctx = canvas.getContext('2d');
+
+test(function(t) {
+
+ assert_array_equals(ctx.getTransform().toFloat32Array(),
+ [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ "Assert that an untransformed matrix is identity");
+
+ ctx.scale(2, 3);
+ transform = ctx.getTransform();
+ assert_array_equals(ctx.getTransform().toFloat32Array(),
+ [2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ "Assert that context2d scaling works");
+
+ ctx.rotate(Math.PI/2);
+ transform = ctx.getTransform();
+ assert_array_approx_equals(ctx.getTransform().toFloat32Array(),
+ [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], epsilon,
+ "Assert that context2d rotate works");
+
+ ctx.translate(1, -1);
+ transform = ctx.getTransform();
+ assert_array_approx_equals(ctx.getTransform().toFloat32Array(),
+ [0, 3, 0, 0, -2, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 1], epsilon,
+ "Assert context2d translate works.");
+
+ ctx.resetTransform();
+ assert_array_equals(ctx.getTransform().toFloat32Array(),
+ [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ "Assert that a reset matrix is identity");
+}, 'This test ensures that getTransform works correctly.');
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/manual/wide-gamut-canvas/2d.color.space.p3.convertToBlobp3.canvas.html b/testing/web-platform/tests/html/canvas/offscreen/manual/wide-gamut-canvas/2d.color.space.p3.convertToBlobp3.canvas.html
new file mode 100644
index 0000000000..9fc63a9f49
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/manual/wide-gamut-canvas/2d.color.space.p3.convertToBlobp3.canvas.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<title>OffscreenCanvas test: 2d.color.space.p3.convertToBlob.p3.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.color.space.p3.convertToBlob.p3.canvas</h1>
+<p class="desc">test if toblob returns p3 data from p3 color space canvas</p>
+
+
+<script>
+var t = async_test("test if toblob returns p3 data from p3 color space canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+var offscreenCanvas = new OffscreenCanvas(100, 50);
+var ctx = offscreenCanvas.getContext('2d', {colorSpace: "display-p3"});
+
+ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ctx.fillRect(0, 0, 1, 1);
+ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ctx.fillRect(1, 0, 1, 1);
+ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ctx.fillRect(0, 1, 1, 1);
+ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ctx.fillRect(1, 1, 1, 1);
+expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+var image = new Image();
+image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+});
+
+offscreenCanvas.convertToBlob(function(blob) {
+ var urlCreator = window.URL || window.webkitURL;
+ image.src = urlCreator.createObjectURL(blob);
+}, 'image/png', 1);
+t.done()
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.html
new file mode 100644
index 0000000000..bdd2c7a65f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.angle.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.angle.1</h1>
+<p class="desc">arc() draws pi/2 .. -pi anticlockwise correctly</p>
+
+
+<script>
+var t = async_test("arc() draws pi/2 .. -pi anticlockwise correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.worker.js
new file mode 100644
index 0000000000..1b6a534c23
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.angle.1
+// Description:arc() draws pi/2 .. -pi anticlockwise correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws pi/2 .. -pi anticlockwise correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.html
new file mode 100644
index 0000000000..c92e83abd7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.angle.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.angle.2</h1>
+<p class="desc">arc() draws -3pi/2 .. -pi anticlockwise correctly</p>
+
+
+<script>
+var t = async_test("arc() draws -3pi/2 .. -pi anticlockwise correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.worker.js
new file mode 100644
index 0000000000..25598c959d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.2.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.angle.2
+// Description:arc() draws -3pi/2 .. -pi anticlockwise correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws -3pi/2 .. -pi anticlockwise correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.html
new file mode 100644
index 0000000000..86170ac8c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.angle.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.angle.3</h1>
+<p class="desc">arc() wraps angles mod 2pi when anticlockwise and end > start+2pi</p>
+
+
+<script>
+var t = async_test("arc() wraps angles mod 2pi when anticlockwise and end > start+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.worker.js
new file mode 100644
index 0000000000..6841041d78
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.3.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.angle.3
+// Description:arc() wraps angles mod 2pi when anticlockwise and end > start+2pi
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() wraps angles mod 2pi when anticlockwise and end > start+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.html
new file mode 100644
index 0000000000..e694b99f70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.angle.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.angle.4</h1>
+<p class="desc">arc() draws a full circle when clockwise and end > start+2pi</p>
+
+
+<script>
+var t = async_test("arc() draws a full circle when clockwise and end > start+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.worker.js
new file mode 100644
index 0000000000..502175165f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.4.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.angle.4
+// Description:arc() draws a full circle when clockwise and end > start+2pi
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws a full circle when clockwise and end > start+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.html
new file mode 100644
index 0000000000..7f0d9af19f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.angle.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.angle.5</h1>
+<p class="desc">arc() wraps angles mod 2pi when clockwise and start > end+2pi</p>
+
+
+<script>
+var t = async_test("arc() wraps angles mod 2pi when clockwise and start > end+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.worker.js
new file mode 100644
index 0000000000..aa2320a92a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.5.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.angle.5
+// Description:arc() wraps angles mod 2pi when clockwise and start > end+2pi
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() wraps angles mod 2pi when clockwise and start > end+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.html
new file mode 100644
index 0000000000..64cf6daeef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.angle.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.angle.6</h1>
+<p class="desc">arc() draws a full circle when anticlockwise and start > end+2pi</p>
+
+
+<script>
+var t = async_test("arc() draws a full circle when anticlockwise and start > end+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.worker.js
new file mode 100644
index 0000000000..929db397d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.angle.6.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.angle.6
+// Description:arc() draws a full circle when anticlockwise and start > end+2pi
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws a full circle when anticlockwise and start > end+2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true);
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.html
new file mode 100644
index 0000000000..ee42c04085
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.default</h1>
+<p class="desc">arc() with missing last argument defaults to clockwise</p>
+
+
+<script>
+var t = async_test("arc() with missing last argument defaults to clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -Math.PI, Math.PI/2);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.worker.js
new file mode 100644
index 0000000000..da74713e4a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.default.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.default
+// Description:arc() with missing last argument defaults to clockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with missing last argument defaults to clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -Math.PI, Math.PI/2);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.html
new file mode 100644
index 0000000000..25414647b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.empty</h1>
+<p class="desc">arc() with an empty path does not draw a straight line to the start point</p>
+
+
+<script>
+var t = async_test("arc() with an empty path does not draw a straight line to the start point");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.worker.js
new file mode 100644
index 0000000000..9b1fbb1a38
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.empty.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.empty
+// Description:arc() with an empty path does not draw a straight line to the start point
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with an empty path does not draw a straight line to the start point");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.html
new file mode 100644
index 0000000000..b8459053f2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.end</h1>
+<p class="desc">arc() adds the end point of the arc to the subpath</p>
+
+
+<script>
+var t = async_test("arc() adds the end point of the arc to the subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(-100, 0);
+ ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.worker.js
new file mode 100644
index 0000000000..963640a273
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.end.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.end
+// Description:arc() adds the end point of the arc to the subpath
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() adds the end point of the arc to the subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(-100, 0);
+ ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.html
new file mode 100644
index 0000000000..6c81b9e0de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.negative</h1>
+<p class="desc">arc() with negative radius throws INDEX_SIZE_ERR</p>
+
+
+<script>
+var t = async_test("arc() with negative radius throws INDEX_SIZE_ERR");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.arc(0, 0, -1, 0, 0, true); });
+ var path = new Path2D();
+ assert_throws_dom("INDEX_SIZE_ERR", function() { path.arc(10, 10, -5, 0, 1, false); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.worker.js
new file mode 100644
index 0000000000..b48eb98474
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.negative.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.negative
+// Description:arc() with negative radius throws INDEX_SIZE_ERR
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with negative radius throws INDEX_SIZE_ERR");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.arc(0, 0, -1, 0, 0, true); });
+ var path = new Path2D();
+ assert_throws_dom("INDEX_SIZE_ERR", function() { path.arc(10, 10, -5, 0, 1, false); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.html
new file mode 100644
index 0000000000..4d9ebe6d87
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.nonempty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.nonempty</h1>
+<p class="desc">arc() with a non-empty path does draw a straight line to the start point</p>
+
+
+<script>
+var t = async_test("arc() with a non-empty path does draw a straight line to the start point");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.worker.js
new file mode 100644
index 0000000000..af6b4c9853
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonempty.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.nonempty
+// Description:arc() with a non-empty path does draw a straight line to the start point
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with a non-empty path does draw a straight line to the start point");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.html
new file mode 100644
index 0000000000..b347a1e27a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.nonfinite</h1>
+<p class="desc">arc() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("arc() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, NaN, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, NaN, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, NaN, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, 0, Infinity, true);
+ ctx.arc(0, 0, 50, 0, -Infinity, true);
+ ctx.arc(0, 0, 50, 0, NaN, true);
+ ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, 0, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, 50, 0, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, 50, 0, Infinity, true);
+ ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, 0, Infinity, 0, Infinity, true);
+ ctx.arc(0, 0, 50, Infinity, Infinity, true);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.worker.js
new file mode 100644
index 0000000000..50ff560e34
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.nonfinite.worker.js
@@ -0,0 +1,72 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.nonfinite
+// Description:arc() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, NaN, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, NaN, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, NaN, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, 0, Infinity, true);
+ ctx.arc(0, 0, 50, 0, -Infinity, true);
+ ctx.arc(0, 0, 50, 0, NaN, true);
+ ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, 0, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, 50, 0, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, 50, 0, Infinity, true);
+ ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, 0, Infinity, 0, Infinity, true);
+ ctx.arc(0, 0, 50, Infinity, Infinity, true);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.html
new file mode 100644
index 0000000000..bf8a6f1f91
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.scale.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.scale.1</h1>
+<p class="desc">Non-uniformly scaled arcs are the right shape</p>
+
+
+<script>
+var t = async_test("Non-uniformly scaled arcs are the right shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(2, 0.5);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(25, 50, 56, 0, 2*Math.PI, false);
+ ctx.fill();
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-25, 50);
+ ctx.arc(-25, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(75, 50);
+ ctx.arc(75, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, -25);
+ ctx.arc(25, -25, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, 125);
+ ctx.arc(25, 125, 24, 0, 2*Math.PI, false);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.worker.js
new file mode 100644
index 0000000000..5d9619a920
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.1.worker.js
@@ -0,0 +1,49 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.scale.1
+// Description:Non-uniformly scaled arcs are the right shape
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Non-uniformly scaled arcs are the right shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(2, 0.5);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(25, 50, 56, 0, 2*Math.PI, false);
+ ctx.fill();
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-25, 50);
+ ctx.arc(-25, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(75, 50);
+ ctx.arc(75, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, -25);
+ ctx.arc(25, -25, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, 125);
+ ctx.arc(25, 125, 24, 0, 2*Math.PI, false);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.html
new file mode 100644
index 0000000000..95376882cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.scale.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.scale.2</h1>
+<p class="desc">Highly scaled arcs are the right shape</p>
+
+
+<script>
+var t = async_test("Highly scaled arcs are the right shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(100, 100);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 1.2;
+ ctx.beginPath();
+ ctx.arc(0, 0, 0.6, 0, Math.PI/2, false);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.worker.js
new file mode 100644
index 0000000000..c655dad30f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.scale.2.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.scale.2
+// Description:Highly scaled arcs are the right shape
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Highly scaled arcs are the right shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(100, 100);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 1.2;
+ ctx.beginPath();
+ ctx.arc(0, 0, 0.6, 0, Math.PI/2, false);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.html
new file mode 100644
index 0000000000..624b307af7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.selfintersect.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.selfintersect.1</h1>
+<p class="desc">arc() with lineWidth > 2*radius is drawn sensibly</p>
+
+
+<script>
+var t = async_test("arc() with lineWidth > 2*radius is drawn sensibly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(100, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.worker.js
new file mode 100644
index 0000000000..6c77dbd5b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.selfintersect.1
+// Description:arc() with lineWidth > 2*radius is drawn sensibly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with lineWidth > 2*radius is drawn sensibly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(100, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.html
new file mode 100644
index 0000000000..b49aa2437a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.selfintersect.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.selfintersect.2</h1>
+<p class="desc">arc() with lineWidth > 2*radius is drawn sensibly</p>
+
+
+<script>
+var t = async_test("arc() with lineWidth > 2*radius is drawn sensibly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 180;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(100, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 97,1, 0,255,0,255);
+ _assertPixel(canvas, 97,2, 0,255,0,255);
+ _assertPixel(canvas, 97,3, 0,255,0,255);
+ _assertPixel(canvas, 2,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.worker.js
new file mode 100644
index 0000000000..2bbdacd46d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.2.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.selfintersect.2
+// Description:arc() with lineWidth > 2*radius is drawn sensibly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with lineWidth > 2*radius is drawn sensibly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 180;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(100, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 97,1, 0,255,0,255);
+ _assertPixel(canvas, 97,2, 0,255,0,255);
+ _assertPixel(canvas, 97,3, 0,255,0,255);
+ _assertPixel(canvas, 2,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.html
new file mode 100644
index 0000000000..ceb3cb380c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.shape.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.shape.1</h1>
+<p class="desc">arc() from 0 to pi does not draw anything in the wrong half</p>
+
+
+<script>
+var t = async_test("arc() from 0 to pi does not draw anything in the wrong half");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 20,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.worker.js
new file mode 100644
index 0000000000..e1058ae96d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.1.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.shape.1
+// Description:arc() from 0 to pi does not draw anything in the wrong half
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() from 0 to pi does not draw anything in the wrong half");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 20,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.html
new file mode 100644
index 0000000000..a39fd03947
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.shape.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.shape.2</h1>
+<p class="desc">arc() from 0 to pi draws stuff in the right half</p>
+
+
+<script>
+var t = async_test("arc() from 0 to pi draws stuff in the right half");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 20,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.worker.js
new file mode 100644
index 0000000000..d444d9b04e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.2.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.shape.2
+// Description:arc() from 0 to pi draws stuff in the right half
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() from 0 to pi draws stuff in the right half");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 20,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.html
new file mode 100644
index 0000000000..853814aef2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.shape.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.shape.3</h1>
+<p class="desc">arc() from 0 to -pi/2 does not draw anything in the wrong quadrant</p>
+
+
+<script>
+var t = async_test("arc() from 0 to -pi/2 does not draw anything in the wrong quadrant");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(0, 50, 50, 0, -Math.PI/2, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.worker.js
new file mode 100644
index 0000000000..b8008e778b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.3.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.shape.3
+// Description:arc() from 0 to -pi/2 does not draw anything in the wrong quadrant
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() from 0 to -pi/2 does not draw anything in the wrong quadrant");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(0, 50, 50, 0, -Math.PI/2, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.html
new file mode 100644
index 0000000000..e6221947df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.shape.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.shape.4</h1>
+<p class="desc">arc() from 0 to -pi/2 draws stuff in the right quadrant</p>
+
+
+<script>
+var t = async_test("arc() from 0 to -pi/2 draws stuff in the right quadrant");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 150;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 100, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.worker.js
new file mode 100644
index 0000000000..9174641c20
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.4.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.shape.4
+// Description:arc() from 0 to -pi/2 draws stuff in the right quadrant
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() from 0 to -pi/2 draws stuff in the right quadrant");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 150;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 100, 0, -Math.PI/2, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.html
new file mode 100644
index 0000000000..968a1c58c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.shape.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.shape.5</h1>
+<p class="desc">arc() from 0 to 5pi does not draw crazy things</p>
+
+
+<script>
+var t = async_test("arc() from 0 to 5pi does not draw crazy things");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(300, 0, 100, 0, 5*Math.PI, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.worker.js
new file mode 100644
index 0000000000..7f40e4341a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.shape.5.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.shape.5
+// Description:arc() from 0 to 5pi does not draw crazy things
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() from 0 to 5pi does not draw crazy things");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(300, 0, 100, 0, 5*Math.PI, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.html
new file mode 100644
index 0000000000..ced1207a9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.twopie.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.twopie.1</h1>
+<p class="desc">arc() draws nothing when end = start + 2pi-e and anticlockwise</p>
+
+
+<script>
+var t = async_test("arc() draws nothing when end = start + 2pi-e and anticlockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.worker.js
new file mode 100644
index 0000000000..e9abf086e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.twopie.1
+// Description:arc() draws nothing when end = start + 2pi-e and anticlockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws nothing when end = start + 2pi-e and anticlockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.html
new file mode 100644
index 0000000000..4948b10f2f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.twopie.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.twopie.2</h1>
+<p class="desc">arc() draws a full circle when end = start + 2pi-e and clockwise</p>
+
+
+<script>
+var t = async_test("arc() draws a full circle when end = start + 2pi-e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.worker.js
new file mode 100644
index 0000000000..5e9c51e5e3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.2.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.twopie.2
+// Description:arc() draws a full circle when end = start + 2pi-e and clockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws a full circle when end = start + 2pi-e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.html
new file mode 100644
index 0000000000..c4036fc06e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.twopie.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.twopie.3</h1>
+<p class="desc">arc() draws a full circle when end = start + 2pi+e and anticlockwise</p>
+
+
+<script>
+var t = async_test("arc() draws a full circle when end = start + 2pi+e and anticlockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.worker.js
new file mode 100644
index 0000000000..ad72fbd0af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.3.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.twopie.3
+// Description:arc() draws a full circle when end = start + 2pi+e and anticlockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws a full circle when end = start + 2pi+e and anticlockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.html
new file mode 100644
index 0000000000..392f00e652
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.twopie.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.twopie.4</h1>
+<p class="desc">arc() draws nothing when end = start + 2pi+e and clockwise</p>
+
+
+<script>
+var t = async_test("arc() draws nothing when end = start + 2pi+e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.worker.js
new file mode 100644
index 0000000000..15d799209c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.4.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.twopie.4
+// Description:arc() draws nothing when end = start + 2pi+e and clockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws nothing when end = start + 2pi+e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.html
new file mode 100644
index 0000000000..17c66c527c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.twopie.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.twopie.5</h1>
+<p class="desc">arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise</p>
+
+
+<script>
+var t = async_test("arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ _assertPixel(canvas, 95,25, 0,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.worker.js
new file mode 100644
index 0000000000..8fa29d5a97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.5.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.twopie.5
+// Description:arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ _assertPixel(canvas, 95,25, 0,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.html
new file mode 100644
index 0000000000..befec82704
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.twopie.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.twopie.6</h1>
+<p class="desc">arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise</p>
+
+
+<script>
+var t = async_test("arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ _assertPixel(canvas, 5,25, 0,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.worker.js
new file mode 100644
index 0000000000..546cbce33c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.twopie.6.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.twopie.6
+// Description:arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ _assertPixel(canvas, 5,25, 0,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.html
new file mode 100644
index 0000000000..5757ab3ddf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.zero.1</h1>
+<p class="desc">arc() draws nothing when startAngle = endAngle and anticlockwise</p>
+
+
+<script>
+var t = async_test("arc() draws nothing when startAngle = endAngle and anticlockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.worker.js
new file mode 100644
index 0000000000..5a6d35f691
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.zero.1
+// Description:arc() draws nothing when startAngle = endAngle and anticlockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws nothing when startAngle = endAngle and anticlockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.html
new file mode 100644
index 0000000000..69f8472443
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.zero.2</h1>
+<p class="desc">arc() draws nothing when startAngle = endAngle and clockwise</p>
+
+
+<script>
+var t = async_test("arc() draws nothing when startAngle = endAngle and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.worker.js
new file mode 100644
index 0000000000..a285462fc0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zero.2.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.zero.2
+// Description:arc() draws nothing when startAngle = endAngle and clockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() draws nothing when startAngle = endAngle and clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, false);
+ ctx.stroke();
+ _assertPixel(canvas, 50,20, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.html
new file mode 100644
index 0000000000..7303b7dc1c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arc.zeroradius</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arc.zeroradius</h1>
+<p class="desc">arc() with zero radius draws a line to the start point</p>
+
+
+<script>
+var t = async_test("arc() with zero radius draws a line to the start point");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00'
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 0, 0, Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.worker.js
new file mode 100644
index 0000000000..183acc1bbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arc.zeroradius.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arc.zeroradius
+// Description:arc() with zero radius draws a line to the start point
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arc() with zero radius draws a line to the start point");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00'
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 0, 0, Math.PI, true);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.html
new file mode 100644
index 0000000000..e7558d628f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.coincide.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.coincide.1</h1>
+<p class="desc">arcTo() has no effect if P0 = P1</p>
+
+
+<script>
+var t = async_test("arcTo() has no effect if P0 = P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(0, 25, 50, 1000, 1);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.worker.js
new file mode 100644
index 0000000000..80a74c6d91
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.1.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.coincide.1
+// Description:arcTo() has no effect if P0 = P1
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() has no effect if P0 = P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(0, 25, 50, 1000, 1);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.html
new file mode 100644
index 0000000000..18ac31524d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.coincide.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.coincide.2</h1>
+<p class="desc">arcTo() draws a straight line to P1 if P1 = P2</p>
+
+
+<script>
+var t = async_test("arcTo() draws a straight line to P1 if P1 = P2");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.worker.js
new file mode 100644
index 0000000000..a35ffe6977
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.coincide.2.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.coincide.2
+// Description:arcTo() draws a straight line to P1 if P1 = P2
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() draws a straight line to P1 if P1 = P2");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.html
new file mode 100644
index 0000000000..b9bcc7b238
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.collinear.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.collinear.1</h1>
+<p class="desc">arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1</p>
+
+
+<script>
+var t = async_test("arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 200, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.worker.js
new file mode 100644
index 0000000000..a814b1af07
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.1.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.collinear.1
+// Description:arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 200, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, 100, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.html
new file mode 100644
index 0000000000..f51a7af206
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.collinear.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.collinear.2</h1>
+<p class="desc">arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1</p>
+
+
+<script>
+var t = async_test("arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 10, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 110, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.worker.js
new file mode 100644
index 0000000000..ba9a75ed4e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.2.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.collinear.2
+// Description:arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 10, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 110, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.html
new file mode 100644
index 0000000000..568d0f8f2b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.collinear.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.collinear.3</h1>
+<p class="desc">arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1</p>
+
+
+<script>
+var t = async_test("arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 0, 25, 1);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, -200, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.worker.js
new file mode 100644
index 0000000000..8087909cb7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.collinear.3.worker.js
@@ -0,0 +1,43 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.collinear.3
+// Description:arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 0, 25, 1);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, -200, 25, 1);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..ec1bd0399d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the first control point is added (and nothing is drawn up to it)</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arcTo(100, 50, 200, 50, 0.1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.worker.js
new file mode 100644
index 0000000000..74d71b6253
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.ensuresubpath.1
+// Description:If there is no subpath, the first control point is added (and nothing is drawn up to it)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arcTo(100, 50, 200, 50, 0.1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..60ee458524
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the first control point is added</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the first control point is added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arcTo(0, 25, 50, 250, 0.1); // adds (x1,y1), draws nothing
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.worker.js
new file mode 100644
index 0000000000..76790925af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.ensuresubpath.2.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.ensuresubpath.2
+// Description:If there is no subpath, the first control point is added
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the first control point is added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arcTo(0, 25, 50, 250, 0.1); // adds (x1,y1), draws nothing
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.html
new file mode 100644
index 0000000000..c35e293a6f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.negative</h1>
+<p class="desc">arcTo() with negative radius throws an exception</p>
+
+
+<script>
+var t = async_test("arcTo() with negative radius throws an exception");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.arcTo(0, 0, 0, 0, -1); });
+ var path = new Path2D();
+ assert_throws_dom("INDEX_SIZE_ERR", function() { path.arcTo(10, 10, 20, 20, -5); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.worker.js
new file mode 100644
index 0000000000..104e7a6387
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.negative.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.negative
+// Description:arcTo() with negative radius throws an exception
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() with negative radius throws an exception");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.arcTo(0, 0, 0, 0, -1); });
+ var path = new Path2D();
+ assert_throws_dom("INDEX_SIZE_ERR", function() { path.arcTo(10, 10, 20, 20, -5); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.html
new file mode 100644
index 0000000000..9d2256d79c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.nonfinite</h1>
+<p class="desc">arcTo() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("arcTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arcTo(Infinity, 50, 0, 50, 0);
+ ctx.arcTo(-Infinity, 50, 0, 50, 0);
+ ctx.arcTo(NaN, 50, 0, 50, 0);
+ ctx.arcTo(0, Infinity, 0, 50, 0);
+ ctx.arcTo(0, -Infinity, 0, 50, 0);
+ ctx.arcTo(0, NaN, 0, 50, 0);
+ ctx.arcTo(0, 50, Infinity, 50, 0);
+ ctx.arcTo(0, 50, -Infinity, 50, 0);
+ ctx.arcTo(0, 50, NaN, 50, 0);
+ ctx.arcTo(0, 50, 0, Infinity, 0);
+ ctx.arcTo(0, 50, 0, -Infinity, 0);
+ ctx.arcTo(0, 50, 0, NaN, 0);
+ ctx.arcTo(0, 50, 0, 50, Infinity);
+ ctx.arcTo(0, 50, 0, 50, -Infinity);
+ ctx.arcTo(0, 50, 0, 50, NaN);
+ ctx.arcTo(Infinity, Infinity, 0, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, 50, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, 50, 0, Infinity, 0);
+ ctx.arcTo(Infinity, 50, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, 0, 50, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(0, Infinity, 0, Infinity, 0);
+ ctx.arcTo(0, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, 0, 50, Infinity);
+ ctx.arcTo(0, 50, Infinity, Infinity, 0);
+ ctx.arcTo(0, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, 50, Infinity, 50, Infinity);
+ ctx.arcTo(0, 50, 0, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.worker.js
new file mode 100644
index 0000000000..1d2c913cfe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.nonfinite.worker.js
@@ -0,0 +1,70 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.nonfinite
+// Description:arcTo() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arcTo(Infinity, 50, 0, 50, 0);
+ ctx.arcTo(-Infinity, 50, 0, 50, 0);
+ ctx.arcTo(NaN, 50, 0, 50, 0);
+ ctx.arcTo(0, Infinity, 0, 50, 0);
+ ctx.arcTo(0, -Infinity, 0, 50, 0);
+ ctx.arcTo(0, NaN, 0, 50, 0);
+ ctx.arcTo(0, 50, Infinity, 50, 0);
+ ctx.arcTo(0, 50, -Infinity, 50, 0);
+ ctx.arcTo(0, 50, NaN, 50, 0);
+ ctx.arcTo(0, 50, 0, Infinity, 0);
+ ctx.arcTo(0, 50, 0, -Infinity, 0);
+ ctx.arcTo(0, 50, 0, NaN, 0);
+ ctx.arcTo(0, 50, 0, 50, Infinity);
+ ctx.arcTo(0, 50, 0, 50, -Infinity);
+ ctx.arcTo(0, 50, 0, 50, NaN);
+ ctx.arcTo(Infinity, Infinity, 0, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, 50, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, 50, 0, Infinity, 0);
+ ctx.arcTo(Infinity, 50, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, 0, 50, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(0, Infinity, 0, Infinity, 0);
+ ctx.arcTo(0, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, 0, 50, Infinity);
+ ctx.arcTo(0, 50, Infinity, Infinity, 0);
+ ctx.arcTo(0, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, 50, Infinity, 50, Infinity);
+ ctx.arcTo(0, 50, 0, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.html
new file mode 100644
index 0000000000..26dfa640ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.scale</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.scale</h1>
+<p class="desc">arcTo scales the curve, not just the control points</p>
+
+
+<script>
+var t = async_test("arcTo scales the curve, not just the control points");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.scale(0.1, 1);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-1000, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.worker.js
new file mode 100644
index 0000000000..dc41e6d92d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.scale.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.scale
+// Description:arcTo scales the curve, not just the control points
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo scales the curve, not just the control points");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.scale(0.1, 1);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-1000, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.html
new file mode 100644
index 0000000000..f7d10dd61a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.shape.curve1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.shape.curve1</h1>
+<p class="desc">arcTo() curves in the right kind of shape</p>
+
+
+<script>
+var t = async_test("arcTo() curves in the right kind of shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 55,19, 0,255,0,255);
+ _assertPixel(canvas, 55,20, 0,255,0,255);
+ _assertPixel(canvas, 55,21, 0,255,0,255);
+ _assertPixel(canvas, 64,22, 0,255,0,255);
+ _assertPixel(canvas, 65,21, 0,255,0,255);
+ _assertPixel(canvas, 72,28, 0,255,0,255);
+ _assertPixel(canvas, 73,27, 0,255,0,255);
+ _assertPixel(canvas, 78,36, 0,255,0,255);
+ _assertPixel(canvas, 79,35, 0,255,0,255);
+ _assertPixel(canvas, 80,44, 0,255,0,255);
+ _assertPixel(canvas, 80,45, 0,255,0,255);
+ _assertPixel(canvas, 80,46, 0,255,0,255);
+ _assertPixel(canvas, 65,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.worker.js
new file mode 100644
index 0000000000..c7e61ab576
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve1.worker.js
@@ -0,0 +1,55 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.shape.curve1
+// Description:arcTo() curves in the right kind of shape
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() curves in the right kind of shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 55,19, 0,255,0,255);
+ _assertPixel(canvas, 55,20, 0,255,0,255);
+ _assertPixel(canvas, 55,21, 0,255,0,255);
+ _assertPixel(canvas, 64,22, 0,255,0,255);
+ _assertPixel(canvas, 65,21, 0,255,0,255);
+ _assertPixel(canvas, 72,28, 0,255,0,255);
+ _assertPixel(canvas, 73,27, 0,255,0,255);
+ _assertPixel(canvas, 78,36, 0,255,0,255);
+ _assertPixel(canvas, 79,35, 0,255,0,255);
+ _assertPixel(canvas, 80,44, 0,255,0,255);
+ _assertPixel(canvas, 80,45, 0,255,0,255);
+ _assertPixel(canvas, 80,46, 0,255,0,255);
+ _assertPixel(canvas, 65,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.html
new file mode 100644
index 0000000000..1a023322b2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.shape.curve2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.shape.curve2</h1>
+<p class="desc">arcTo() curves in the right kind of shape</p>
+
+
+<script>
+var t = async_test("arcTo() curves in the right kind of shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 55,19, 0,255,0,255);
+ _assertPixel(canvas, 55,20, 0,255,0,255);
+ _assertPixel(canvas, 55,21, 0,255,0,255);
+ _assertPixel(canvas, 64,22, 0,255,0,255);
+ _assertPixel(canvas, 65,21, 0,255,0,255);
+ _assertPixel(canvas, 72,28, 0,255,0,255);
+ _assertPixel(canvas, 73,27, 0,255,0,255);
+ _assertPixel(canvas, 78,36, 0,255,0,255);
+ _assertPixel(canvas, 79,35, 0,255,0,255);
+ _assertPixel(canvas, 80,44, 0,255,0,255);
+ _assertPixel(canvas, 80,45, 0,255,0,255);
+ _assertPixel(canvas, 80,46, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.worker.js
new file mode 100644
index 0000000000..f00e506f30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.curve2.worker.js
@@ -0,0 +1,54 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.shape.curve2
+// Description:arcTo() curves in the right kind of shape
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() curves in the right kind of shape");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 55,19, 0,255,0,255);
+ _assertPixel(canvas, 55,20, 0,255,0,255);
+ _assertPixel(canvas, 55,21, 0,255,0,255);
+ _assertPixel(canvas, 64,22, 0,255,0,255);
+ _assertPixel(canvas, 65,21, 0,255,0,255);
+ _assertPixel(canvas, 72,28, 0,255,0,255);
+ _assertPixel(canvas, 73,27, 0,255,0,255);
+ _assertPixel(canvas, 78,36, 0,255,0,255);
+ _assertPixel(canvas, 79,35, 0,255,0,255);
+ _assertPixel(canvas, 80,44, 0,255,0,255);
+ _assertPixel(canvas, 80,45, 0,255,0,255);
+ _assertPixel(canvas, 80,46, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.html
new file mode 100644
index 0000000000..3f8af61215
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.shape.end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.shape.end</h1>
+<p class="desc">arcTo() does not draw anything from P1 to P2</p>
+
+
+<script>
+var t = async_test("arcTo() does not draw anything from P1 to P2");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.arcTo(-100, 25, 200, 25, 10);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.worker.js
new file mode 100644
index 0000000000..20cc956a44
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.end.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.shape.end
+// Description:arcTo() does not draw anything from P1 to P2
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() does not draw anything from P1 to P2");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.arcTo(-100, 25, 200, 25, 10);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.html
new file mode 100644
index 0000000000..a426a19d8a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.shape.start</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.shape.start</h1>
+<p class="desc">arcTo() draws a straight line from P0 to P1</p>
+
+
+<script>
+var t = async_test("arcTo() draws a straight line from P0 to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(200, 25, 200, 50, 10);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.worker.js
new file mode 100644
index 0000000000..cebf27a821
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.shape.start.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.shape.start
+// Description:arcTo() draws a straight line from P0 to P1
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() draws a straight line from P0 to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(200, 25, 200, 50, 10);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.html
new file mode 100644
index 0000000000..842210138a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.transformation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.transformation</h1>
+<p class="desc">arcTo joins up to the last subpath point correctly</p>
+
+
+<script>
+var t = async_test("arcTo joins up to the last subpath point correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.worker.js
new file mode 100644
index 0000000000..585a500079
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.transformation.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.transformation
+// Description:arcTo joins up to the last subpath point correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo joins up to the last subpath point correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.html
new file mode 100644
index 0000000000..a367385551
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.zero.1</h1>
+<p class="desc">arcTo() with zero radius draws a straight line from P0 to P1</p>
+
+
+<script>
+var t = async_test("arcTo() with zero radius draws a straight line from P0 to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 100, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(0, -25);
+ ctx.arcTo(50, -25, 50, 50, 0);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.worker.js
new file mode 100644
index 0000000000..8f6d979a55
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.1.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.zero.1
+// Description:arcTo() with zero radius draws a straight line from P0 to P1
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() with zero radius draws a straight line from P0 to P1");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 100, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(0, -25);
+ ctx.arcTo(50, -25, 50, 50, 0);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.html
new file mode 100644
index 0000000000..87ab4e13de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.arcTo.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.arcTo.zero.2</h1>
+<p class="desc">arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear</p>
+
+
+<script>
+var t = async_test("arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 50, 25, 0);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.worker.js
new file mode 100644
index 0000000000..0a45976325
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.arcTo.zero.2.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.arcTo.zero.2
+// Description:arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 50, 25, 0);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.html
new file mode 100644
index 0000000000..b2043d604d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.beginPath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.beginPath</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.worker.js
new file mode 100644
index 0000000000..35a4acc84d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.beginPath.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.beginPath
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.html
new file mode 100644
index 0000000000..099919060b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.bezierCurveTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.bezierCurveTo.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.worker.js
new file mode 100644
index 0000000000..e7c86a08f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.basic.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.bezierCurveTo.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..6a11d1bfbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.bezierCurveTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.bezierCurveTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the first control point is added (and nothing is drawn up to it)</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(100, 50, 200, 50, 200, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 95,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.worker.js
new file mode 100644
index 0000000000..d6ef6f3f1b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.1.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.bezierCurveTo.ensuresubpath.1
+// Description:If there is no subpath, the first control point is added (and nothing is drawn up to it)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(100, 50, 200, 50, 200, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 95,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..d2afd19f66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.bezierCurveTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.bezierCurveTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the first control point is added</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the first control point is added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(0, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.worker.js
new file mode 100644
index 0000000000..6860e60f4a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.ensuresubpath.2.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.bezierCurveTo.ensuresubpath.2
+// Description:If there is no subpath, the first control point is added
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the first control point is added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(0, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.html
new file mode 100644
index 0000000000..b49e2f43f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.bezierCurveTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.bezierCurveTo.nonfinite</h1>
+<p class="desc">bezierCurveTo() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("bezierCurveTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(-Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(NaN, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, -Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, NaN, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, -Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, NaN, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, -Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, NaN, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, -Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, NaN, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, -Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, NaN);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.worker.js
new file mode 100644
index 0000000000..7eaf278f6c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.nonfinite.worker.js
@@ -0,0 +1,104 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.bezierCurveTo.nonfinite
+// Description:bezierCurveTo() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("bezierCurveTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(-Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(NaN, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, -Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, NaN, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, -Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, NaN, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, -Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, NaN, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, -Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, NaN, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, -Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, NaN);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.html
new file mode 100644
index 0000000000..10a085e9de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.bezierCurveTo.scaled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.bezierCurveTo.scaled</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-2, 3.1);
+ ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.worker.js
new file mode 100644
index 0000000000..5098fe83eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.scaled.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.bezierCurveTo.scaled
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-2, 3.1);
+ ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.html
new file mode 100644
index 0000000000..fc6b9273e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.bezierCurveTo.shape</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.bezierCurveTo.shape</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-2000, 3100);
+ ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.worker.js
new file mode 100644
index 0000000000..58f601c5d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.bezierCurveTo.shape.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.bezierCurveTo.shape
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-2000, 3100);
+ ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.html
new file mode 100644
index 0000000000..e90be3d73f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.clip.basic.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.clip.basic.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.worker.js
new file mode 100644
index 0000000000..708608e1e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.1.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.clip.basic.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.html
new file mode 100644
index 0000000000..6426ba2d83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.clip.basic.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.clip.basic.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(-100, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.worker.js
new file mode 100644
index 0000000000..1ec28b6205
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.basic.2.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.clip.basic.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(-100, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.html
new file mode 100644
index 0000000000..30e0d6cba4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.clip.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.clip.empty</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.worker.js
new file mode 100644
index 0000000000..3f91a7e2e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.empty.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.clip.empty
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.html
new file mode 100644
index 0000000000..94607f6d92
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.clip.intersect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.clip.intersect</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50)
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.worker.js
new file mode 100644
index 0000000000..8c0fcb68bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.clip.intersect
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50)
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.html
new file mode 100644
index 0000000000..e9b69282af
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.clip.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.clip.unaffected</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.lineTo(0, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.worker.js
new file mode 100644
index 0000000000..d65a421d33
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.unaffected.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.clip.unaffected
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.lineTo(0, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.html
new file mode 100644
index 0000000000..2fd7c1abbf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.clip.winding.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.clip.winding.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.worker.js
new file mode 100644
index 0000000000..aa89fd55c3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.1.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.clip.winding.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.html
new file mode 100644
index 0000000000..eed064f84e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.clip.winding.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.clip.winding.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.clip();
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.worker.js
new file mode 100644
index 0000000000..5c9cac6bb6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.2.worker.js
@@ -0,0 +1,44 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.clip.winding.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.clip();
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.html
new file mode 100644
index 0000000000..c7596a8f1c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.closePath.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.closePath.empty</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.worker.js
new file mode 100644
index 0000000000..c9a4030e68
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.empty.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.closePath.empty
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.html
new file mode 100644
index 0000000000..771f3d3ca0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.closePath.newline</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.closePath.newline</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.closePath();
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.worker.js
new file mode 100644
index 0000000000..4dff932086
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.newline.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.closePath.newline
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.closePath();
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.html
new file mode 100644
index 0000000000..3dffdeaf5b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.closePath.nextpoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.closePath.nextpoint</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -1000);
+ ctx.closePath();
+ ctx.lineTo(1000, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.worker.js
new file mode 100644
index 0000000000..86d931b671
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.closePath.nextpoint.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.closePath.nextpoint
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -1000);
+ ctx.closePath();
+ ctx.lineTo(1000, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.html
new file mode 100644
index 0000000000..d664c45593
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.ellipse.basics</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.ellipse.basics</h1>
+<p class="desc">Verify canvas throws error when drawing ellipse with negative radii.</p>
+
+
+<script>
+var t = async_test("Verify canvas throws error when drawing ellipse with negative radii.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.ellipse(10, 10, 10, 5, 0, 0, 1, false);
+ ctx.ellipse(10, 10, 10, 0, 0, 0, 1, false);
+ ctx.ellipse(10, 10, -0, 5, 0, 0, 1, false);
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, -2, 5, 0, 0, 1, false); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, 0, -1.5, 0, 0, 1, false); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, -2, -5, 0, 0, 1, false); });
+ ctx.ellipse(80, 0, 10, 4294967277, Math.PI / -84, -Math.PI / 2147483436, false);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.worker.js
new file mode 100644
index 0000000000..60f3e9a673
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.ellipse.basics.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.ellipse.basics
+// Description:Verify canvas throws error when drawing ellipse with negative radii.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify canvas throws error when drawing ellipse with negative radii.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.ellipse(10, 10, 10, 5, 0, 0, 1, false);
+ ctx.ellipse(10, 10, 10, 0, 0, 0, 1, false);
+ ctx.ellipse(10, 10, -0, 5, 0, 0, 1, false);
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, -2, 5, 0, 0, 1, false); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, 0, -1.5, 0, 0, 1, false); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.ellipse(10, 10, -2, -5, 0, 0, 1, false); });
+ ctx.ellipse(80, 0, 10, 4294967277, Math.PI / -84, -Math.PI / 2147483436, false);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.html
new file mode 100644
index 0000000000..6f8fd51de7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.fill.closed.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.fill.closed.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.worker.js
new file mode 100644
index 0000000000..9dad73b579
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.basic.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.fill.closed.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.html
new file mode 100644
index 0000000000..706e38d176
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.fill.closed.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.fill.closed.unaffected</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 10,40, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.worker.js
new file mode 100644
index 0000000000..b6d7982866
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.closed.unaffected.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.fill.closed.unaffected
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 90,10, 0,255,0,255);
+ _assertPixel(canvas, 10,40, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.html
new file mode 100644
index 0000000000..da936fab57
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.fill.overlap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.fill.overlap</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.rect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.rect(10, 10, 80, 30);
+ ctx.fill();
+
+ _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.png b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.png
new file mode 100644
index 0000000000..e2a35d48d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.worker.js
new file mode 100644
index 0000000000..8f30cc7af2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.overlap.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.fill.overlap
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.rect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.rect(10, 10, 80, 30);
+ ctx.fill();
+
+ _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.html
new file mode 100644
index 0000000000..40845a4a77
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.fill.winding.add</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.fill.winding.add</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.worker.js
new file mode 100644
index 0000000000..cdbfc7f3a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.add.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.fill.winding.add
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.html
new file mode 100644
index 0000000000..e0f9c838b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.fill.winding.subtract.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.fill.winding.subtract.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.worker.js
new file mode 100644
index 0000000000..3d6a1660de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.1.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.fill.winding.subtract.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.html
new file mode 100644
index 0000000000..c7de03ae08
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.fill.winding.subtract.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.fill.winding.subtract.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.worker.js
new file mode 100644
index 0000000000..0e8b4c79a5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.2.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.fill.winding.subtract.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.html
new file mode 100644
index 0000000000..3d12380357
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.fill.winding.subtract.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.fill.winding.subtract.3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(120, -20);
+ ctx.lineTo(120, 70);
+ ctx.lineTo(-20, 70);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.worker.js
new file mode 100644
index 0000000000..6c9f07c76a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.subtract.3.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.fill.winding.subtract.3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(120, -20);
+ ctx.lineTo(120, 70);
+ ctx.lineTo(-20, 70);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.html
new file mode 100644
index 0000000000..e2e02f5142
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.initial</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.worker.js
new file mode 100644
index 0000000000..de1a935032
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.initial.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.initial
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.html
new file mode 100644
index 0000000000..ccffcd7d76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.arc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.arc</h1>
+<p class="desc">isPointInPath() works on arcs</p>
+
+
+<script>
+var t = async_test("isPointInPath() works on arcs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.arc(50, 25, 10, 0, Math.PI, false);
+ _assertSame(ctx.isPointInPath(50, 10), false, "ctx.isPointInPath(50, 10)", "false");
+ _assertSame(ctx.isPointInPath(50, 20), false, "ctx.isPointInPath(50, 20)", "false");
+ _assertSame(ctx.isPointInPath(50, 30), true, "ctx.isPointInPath(50, 30)", "true");
+ _assertSame(ctx.isPointInPath(50, 40), false, "ctx.isPointInPath(50, 40)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), false, "ctx.isPointInPath(70, 30)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.worker.js
new file mode 100644
index 0000000000..13510b744f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.arc.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.arc
+// Description:isPointInPath() works on arcs
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() works on arcs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.arc(50, 25, 10, 0, Math.PI, false);
+ _assertSame(ctx.isPointInPath(50, 10), false, "ctx.isPointInPath(50, 10)", "false");
+ _assertSame(ctx.isPointInPath(50, 20), false, "ctx.isPointInPath(50, 20)", "false");
+ _assertSame(ctx.isPointInPath(50, 30), true, "ctx.isPointInPath(50, 30)", "true");
+ _assertSame(ctx.isPointInPath(50, 40), false, "ctx.isPointInPath(50, 40)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), false, "ctx.isPointInPath(70, 30)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.html
new file mode 100644
index 0000000000..7b9673a812
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.basic.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.basic.1</h1>
+<p class="desc">isPointInPath() detects whether the point is inside the path</p>
+
+
+<script>
+var t = async_test("isPointInPath() detects whether the point is inside the path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), true, "ctx.isPointInPath(10, 10)", "true");
+ _assertSame(ctx.isPointInPath(30, 10), false, "ctx.isPointInPath(30, 10)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.worker.js
new file mode 100644
index 0000000000..f51900ea6b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.1.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.basic.1
+// Description:isPointInPath() detects whether the point is inside the path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() detects whether the point is inside the path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), true, "ctx.isPointInPath(10, 10)", "true");
+ _assertSame(ctx.isPointInPath(30, 10), false, "ctx.isPointInPath(30, 10)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.html
new file mode 100644
index 0000000000..3710dd185d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.basic.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.basic.2</h1>
+<p class="desc">isPointInPath() detects whether the point is inside the path</p>
+
+
+<script>
+var t = async_test("isPointInPath() detects whether the point is inside the path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(20, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(30, 10), true, "ctx.isPointInPath(30, 10)", "true");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.worker.js
new file mode 100644
index 0000000000..6024a0dc39
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.2.worker.js
@@ -0,0 +1,24 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.basic.2
+// Description:isPointInPath() detects whether the point is inside the path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() detects whether the point is inside the path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(20, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(30, 10), true, "ctx.isPointInPath(30, 10)", "true");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.html
new file mode 100644
index 0000000000..21cf448de2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.basic</h1>
+<p class="desc">Verify the winding rule in isPointInPath works for for rect path.</p>
+
+
+<script>
+var t = async_test("Verify the winding rule in isPointInPath works for for rect path.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50), true, "ctx.isPointInPath(50, 50)", "true");
+ _assertSame(ctx.isPointInPath(NaN, 50), false, "ctx.isPointInPath(NaN, 50)", "false");
+ _assertSame(ctx.isPointInPath(50, NaN), false, "ctx.isPointInPath(50, NaN)", "false");
+
+ // Testing nonzero isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50, 'nonzero'), true, "ctx.isPointInPath(50, 50, 'nonzero')", "true");
+
+ // Testing evenodd isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50, 'evenodd'), false, "ctx.isPointInPath(50, 50, 'evenodd')", "false");
+
+ // Testing extremely large scale
+ ctx.save();
+ ctx.scale(Number.MAX_VALUE, Number.MAX_VALUE);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0, 'nonzero'), true, "ctx.isPointInPath(0, 0, 'nonzero')", "true");
+ _assertSame(ctx.isPointInPath(0, 0, 'evenodd'), true, "ctx.isPointInPath(0, 0, 'evenodd')", "true");
+ ctx.restore();
+
+ // Check with non-invertible ctm.
+ ctx.save();
+ ctx.scale(0, 0);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0, 'nonzero'), false, "ctx.isPointInPath(0, 0, 'nonzero')", "false");
+ _assertSame(ctx.isPointInPath(0, 0, 'evenodd'), false, "ctx.isPointInPath(0, 0, 'evenodd')", "false");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.worker.js
new file mode 100644
index 0000000000..3e2a95c15e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.basic.worker.js
@@ -0,0 +1,61 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.basic
+// Description:Verify the winding rule in isPointInPath works for for rect path.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify the winding rule in isPointInPath works for for rect path.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50), true, "ctx.isPointInPath(50, 50)", "true");
+ _assertSame(ctx.isPointInPath(NaN, 50), false, "ctx.isPointInPath(NaN, 50)", "false");
+ _assertSame(ctx.isPointInPath(50, NaN), false, "ctx.isPointInPath(50, NaN)", "false");
+
+ // Testing nonzero isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50, 'nonzero'), true, "ctx.isPointInPath(50, 50, 'nonzero')", "true");
+
+ // Testing evenodd isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(50, 50, 'evenodd'), false, "ctx.isPointInPath(50, 50, 'evenodd')", "false");
+
+ // Testing extremely large scale
+ ctx.save();
+ ctx.scale(Number.MAX_VALUE, Number.MAX_VALUE);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0, 'nonzero'), true, "ctx.isPointInPath(0, 0, 'nonzero')", "true");
+ _assertSame(ctx.isPointInPath(0, 0, 'evenodd'), true, "ctx.isPointInPath(0, 0, 'evenodd')", "true");
+ ctx.restore();
+
+ // Check with non-invertible ctm.
+ ctx.save();
+ ctx.scale(0, 0);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0, 'nonzero'), false, "ctx.isPointInPath(0, 0, 'nonzero')", "false");
+ _assertSame(ctx.isPointInPath(0, 0, 'evenodd'), false, "ctx.isPointInPath(0, 0, 'evenodd')", "false");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.html
new file mode 100644
index 0000000000..d348110305
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.bezier</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.bezier</h1>
+<p class="desc">isPointInPath() works on Bezier curves</p>
+
+
+<script>
+var t = async_test("isPointInPath() works on Bezier curves");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(25, 25);
+ ctx.bezierCurveTo(50, -50, 50, 100, 75, 25);
+ _assertSame(ctx.isPointInPath(25, 20), false, "ctx.isPointInPath(25, 20)", "false");
+ _assertSame(ctx.isPointInPath(25, 30), false, "ctx.isPointInPath(25, 30)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), true, "ctx.isPointInPath(30, 20)", "true");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(40, 2), false, "ctx.isPointInPath(40, 2)", "false");
+ _assertSame(ctx.isPointInPath(40, 20), true, "ctx.isPointInPath(40, 20)", "true");
+ _assertSame(ctx.isPointInPath(40, 30), false, "ctx.isPointInPath(40, 30)", "false");
+ _assertSame(ctx.isPointInPath(40, 47), false, "ctx.isPointInPath(40, 47)", "false");
+ _assertSame(ctx.isPointInPath(45, 20), true, "ctx.isPointInPath(45, 20)", "true");
+ _assertSame(ctx.isPointInPath(45, 30), false, "ctx.isPointInPath(45, 30)", "false");
+ _assertSame(ctx.isPointInPath(55, 20), false, "ctx.isPointInPath(55, 20)", "false");
+ _assertSame(ctx.isPointInPath(55, 30), true, "ctx.isPointInPath(55, 30)", "true");
+ _assertSame(ctx.isPointInPath(60, 2), false, "ctx.isPointInPath(60, 2)", "false");
+ _assertSame(ctx.isPointInPath(60, 20), false, "ctx.isPointInPath(60, 20)", "false");
+ _assertSame(ctx.isPointInPath(60, 30), true, "ctx.isPointInPath(60, 30)", "true");
+ _assertSame(ctx.isPointInPath(60, 47), false, "ctx.isPointInPath(60, 47)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), true, "ctx.isPointInPath(70, 30)", "true");
+ _assertSame(ctx.isPointInPath(75, 20), false, "ctx.isPointInPath(75, 20)", "false");
+ _assertSame(ctx.isPointInPath(75, 30), false, "ctx.isPointInPath(75, 30)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.worker.js
new file mode 100644
index 0000000000..894fe5da31
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bezier.worker.js
@@ -0,0 +1,43 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.bezier
+// Description:isPointInPath() works on Bezier curves
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() works on Bezier curves");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(25, 25);
+ ctx.bezierCurveTo(50, -50, 50, 100, 75, 25);
+ _assertSame(ctx.isPointInPath(25, 20), false, "ctx.isPointInPath(25, 20)", "false");
+ _assertSame(ctx.isPointInPath(25, 30), false, "ctx.isPointInPath(25, 30)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), true, "ctx.isPointInPath(30, 20)", "true");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(40, 2), false, "ctx.isPointInPath(40, 2)", "false");
+ _assertSame(ctx.isPointInPath(40, 20), true, "ctx.isPointInPath(40, 20)", "true");
+ _assertSame(ctx.isPointInPath(40, 30), false, "ctx.isPointInPath(40, 30)", "false");
+ _assertSame(ctx.isPointInPath(40, 47), false, "ctx.isPointInPath(40, 47)", "false");
+ _assertSame(ctx.isPointInPath(45, 20), true, "ctx.isPointInPath(45, 20)", "true");
+ _assertSame(ctx.isPointInPath(45, 30), false, "ctx.isPointInPath(45, 30)", "false");
+ _assertSame(ctx.isPointInPath(55, 20), false, "ctx.isPointInPath(55, 20)", "false");
+ _assertSame(ctx.isPointInPath(55, 30), true, "ctx.isPointInPath(55, 30)", "true");
+ _assertSame(ctx.isPointInPath(60, 2), false, "ctx.isPointInPath(60, 2)", "false");
+ _assertSame(ctx.isPointInPath(60, 20), false, "ctx.isPointInPath(60, 20)", "false");
+ _assertSame(ctx.isPointInPath(60, 30), true, "ctx.isPointInPath(60, 30)", "true");
+ _assertSame(ctx.isPointInPath(60, 47), false, "ctx.isPointInPath(60, 47)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), true, "ctx.isPointInPath(70, 30)", "true");
+ _assertSame(ctx.isPointInPath(75, 20), false, "ctx.isPointInPath(75, 20)", "false");
+ _assertSame(ctx.isPointInPath(75, 30), false, "ctx.isPointInPath(75, 30)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.html
new file mode 100644
index 0000000000..fcb4ca8827
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.bigarc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.bigarc</h1>
+<p class="desc">isPointInPath() works on unclosed arcs larger than 2pi</p>
+
+
+<script>
+var t = async_test("isPointInPath() works on unclosed arcs larger than 2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.arc(50, 25, 10, 0, 7, false);
+ _assertSame(ctx.isPointInPath(50, 10), false, "ctx.isPointInPath(50, 10)", "false");
+ _assertSame(ctx.isPointInPath(50, 20), true, "ctx.isPointInPath(50, 20)", "true");
+ _assertSame(ctx.isPointInPath(50, 30), true, "ctx.isPointInPath(50, 30)", "true");
+ _assertSame(ctx.isPointInPath(50, 40), false, "ctx.isPointInPath(50, 40)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), false, "ctx.isPointInPath(70, 30)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.worker.js
new file mode 100644
index 0000000000..40233790c8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.bigarc.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.bigarc
+// Description:isPointInPath() works on unclosed arcs larger than 2pi
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() works on unclosed arcs larger than 2pi");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.arc(50, 25, 10, 0, 7, false);
+ _assertSame(ctx.isPointInPath(50, 10), false, "ctx.isPointInPath(50, 10)", "false");
+ _assertSame(ctx.isPointInPath(50, 20), true, "ctx.isPointInPath(50, 20)", "true");
+ _assertSame(ctx.isPointInPath(50, 30), true, "ctx.isPointInPath(50, 30)", "true");
+ _assertSame(ctx.isPointInPath(50, 40), false, "ctx.isPointInPath(50, 40)", "false");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ _assertSame(ctx.isPointInPath(70, 20), false, "ctx.isPointInPath(70, 20)", "false");
+ _assertSame(ctx.isPointInPath(30, 30), false, "ctx.isPointInPath(30, 30)", "false");
+ _assertSame(ctx.isPointInPath(70, 30), false, "ctx.isPointInPath(70, 30)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.html
new file mode 100644
index 0000000000..aa367b4e56
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.edge</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.edge</h1>
+<p class="desc">isPointInPath() counts points on the path as being inside</p>
+
+
+<script>
+var t = async_test("isPointInPath() counts points on the path as being inside");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0), true, "ctx.isPointInPath(0, 0)", "true");
+ _assertSame(ctx.isPointInPath(10, 0), true, "ctx.isPointInPath(10, 0)", "true");
+ _assertSame(ctx.isPointInPath(20, 0), true, "ctx.isPointInPath(20, 0)", "true");
+ _assertSame(ctx.isPointInPath(20, 10), true, "ctx.isPointInPath(20, 10)", "true");
+ _assertSame(ctx.isPointInPath(20, 20), true, "ctx.isPointInPath(20, 20)", "true");
+ _assertSame(ctx.isPointInPath(10, 20), true, "ctx.isPointInPath(10, 20)", "true");
+ _assertSame(ctx.isPointInPath(0, 20), true, "ctx.isPointInPath(0, 20)", "true");
+ _assertSame(ctx.isPointInPath(0, 10), true, "ctx.isPointInPath(0, 10)", "true");
+ _assertSame(ctx.isPointInPath(10, -0.01), false, "ctx.isPointInPath(10, -0.01)", "false");
+ _assertSame(ctx.isPointInPath(10, 20.01), false, "ctx.isPointInPath(10, 20.01)", "false");
+ _assertSame(ctx.isPointInPath(-0.01, 10), false, "ctx.isPointInPath(-0.01, 10)", "false");
+ _assertSame(ctx.isPointInPath(20.01, 10), false, "ctx.isPointInPath(20.01, 10)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.worker.js
new file mode 100644
index 0000000000..3918a6fe83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.edge.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.edge
+// Description:isPointInPath() counts points on the path as being inside
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() counts points on the path as being inside");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(0, 0), true, "ctx.isPointInPath(0, 0)", "true");
+ _assertSame(ctx.isPointInPath(10, 0), true, "ctx.isPointInPath(10, 0)", "true");
+ _assertSame(ctx.isPointInPath(20, 0), true, "ctx.isPointInPath(20, 0)", "true");
+ _assertSame(ctx.isPointInPath(20, 10), true, "ctx.isPointInPath(20, 10)", "true");
+ _assertSame(ctx.isPointInPath(20, 20), true, "ctx.isPointInPath(20, 20)", "true");
+ _assertSame(ctx.isPointInPath(10, 20), true, "ctx.isPointInPath(10, 20)", "true");
+ _assertSame(ctx.isPointInPath(0, 20), true, "ctx.isPointInPath(0, 20)", "true");
+ _assertSame(ctx.isPointInPath(0, 10), true, "ctx.isPointInPath(0, 10)", "true");
+ _assertSame(ctx.isPointInPath(10, -0.01), false, "ctx.isPointInPath(10, -0.01)", "false");
+ _assertSame(ctx.isPointInPath(10, 20.01), false, "ctx.isPointInPath(10, 20.01)", "false");
+ _assertSame(ctx.isPointInPath(-0.01, 10), false, "ctx.isPointInPath(-0.01, 10)", "false");
+ _assertSame(ctx.isPointInPath(20.01, 10), false, "ctx.isPointInPath(20.01, 10)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.html
new file mode 100644
index 0000000000..d2ebf1e7e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.empty</h1>
+<p class="desc">isPointInPath() works when there is no path</p>
+
+
+<script>
+var t = async_test("isPointInPath() works when there is no path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.isPointInPath(0, 0), false, "ctx.isPointInPath(0, 0)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.worker.js
new file mode 100644
index 0000000000..319836dcb5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.empty.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.empty
+// Description:isPointInPath() works when there is no path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() works when there is no path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.isPointInPath(0, 0), false, "ctx.isPointInPath(0, 0)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.html
new file mode 100644
index 0000000000..ef12d057ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.nonfinite</h1>
+<p class="desc">isPointInPath() returns false for non-finite arguments</p>
+
+
+<script>
+var t = async_test("isPointInPath() returns false for non-finite arguments");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(-100, -50, 200, 100);
+ _assertSame(ctx.isPointInPath(Infinity, 0), false, "ctx.isPointInPath(Infinity, 0)", "false");
+ _assertSame(ctx.isPointInPath(-Infinity, 0), false, "ctx.isPointInPath(-Infinity, 0)", "false");
+ _assertSame(ctx.isPointInPath(NaN, 0), false, "ctx.isPointInPath(NaN, 0)", "false");
+ _assertSame(ctx.isPointInPath(0, Infinity), false, "ctx.isPointInPath(0, Infinity)", "false");
+ _assertSame(ctx.isPointInPath(0, -Infinity), false, "ctx.isPointInPath(0, -Infinity)", "false");
+ _assertSame(ctx.isPointInPath(0, NaN), false, "ctx.isPointInPath(0, NaN)", "false");
+ _assertSame(ctx.isPointInPath(NaN, NaN), false, "ctx.isPointInPath(NaN, NaN)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.worker.js
new file mode 100644
index 0000000000..dfa6eec766
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nonfinite.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.nonfinite
+// Description:isPointInPath() returns false for non-finite arguments
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() returns false for non-finite arguments");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(-100, -50, 200, 100);
+ _assertSame(ctx.isPointInPath(Infinity, 0), false, "ctx.isPointInPath(Infinity, 0)", "false");
+ _assertSame(ctx.isPointInPath(-Infinity, 0), false, "ctx.isPointInPath(-Infinity, 0)", "false");
+ _assertSame(ctx.isPointInPath(NaN, 0), false, "ctx.isPointInPath(NaN, 0)", "false");
+ _assertSame(ctx.isPointInPath(0, Infinity), false, "ctx.isPointInPath(0, Infinity)", "false");
+ _assertSame(ctx.isPointInPath(0, -Infinity), false, "ctx.isPointInPath(0, -Infinity)", "false");
+ _assertSame(ctx.isPointInPath(0, NaN), false, "ctx.isPointInPath(0, NaN)", "false");
+ _assertSame(ctx.isPointInPath(NaN, NaN), false, "ctx.isPointInPath(NaN, NaN)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.html
new file mode 100644
index 0000000000..ce2ab819dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.outside</h1>
+<p class="desc">isPointInPath() works on paths outside the canvas</p>
+
+
+<script>
+var t = async_test("isPointInPath() works on paths outside the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, -100, 20, 20);
+ ctx.rect(20, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(10, -110), false, "ctx.isPointInPath(10, -110)", "false");
+ _assertSame(ctx.isPointInPath(10, -90), true, "ctx.isPointInPath(10, -90)", "true");
+ _assertSame(ctx.isPointInPath(10, -70), false, "ctx.isPointInPath(10, -70)", "false");
+ _assertSame(ctx.isPointInPath(30, -20), false, "ctx.isPointInPath(30, -20)", "false");
+ _assertSame(ctx.isPointInPath(30, 0), true, "ctx.isPointInPath(30, 0)", "true");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.worker.js
new file mode 100644
index 0000000000..d4db12ef37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.outside.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.outside
+// Description:isPointInPath() works on paths outside the canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() works on paths outside the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, -100, 20, 20);
+ ctx.rect(20, -10, 20, 20);
+ _assertSame(ctx.isPointInPath(10, -110), false, "ctx.isPointInPath(10, -110)", "false");
+ _assertSame(ctx.isPointInPath(10, -90), true, "ctx.isPointInPath(10, -90)", "true");
+ _assertSame(ctx.isPointInPath(10, -70), false, "ctx.isPointInPath(10, -70)", "false");
+ _assertSame(ctx.isPointInPath(30, -20), false, "ctx.isPointInPath(30, -20)", "false");
+ _assertSame(ctx.isPointInPath(30, 0), true, "ctx.isPointInPath(30, 0)", "true");
+ _assertSame(ctx.isPointInPath(30, 20), false, "ctx.isPointInPath(30, 20)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.html
new file mode 100644
index 0000000000..c4abd92764
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.subpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.subpath</h1>
+<p class="desc">isPointInPath() uses the current path, not just the subpath</p>
+
+
+<script>
+var t = async_test("isPointInPath() uses the current path, not just the subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, 0, 20, 20);
+ ctx.beginPath();
+ ctx.rect(20, 0, 20, 20);
+ ctx.closePath();
+ ctx.rect(40, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(30, 10), true, "ctx.isPointInPath(30, 10)", "true");
+ _assertSame(ctx.isPointInPath(50, 10), true, "ctx.isPointInPath(50, 10)", "true");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.worker.js
new file mode 100644
index 0000000000..82df3b7c70
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.subpath.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.subpath
+// Description:isPointInPath() uses the current path, not just the subpath
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() uses the current path, not just the subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(0, 0, 20, 20);
+ ctx.beginPath();
+ ctx.rect(20, 0, 20, 20);
+ ctx.closePath();
+ ctx.rect(40, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(30, 10), true, "ctx.isPointInPath(30, 10)", "true");
+ _assertSame(ctx.isPointInPath(50, 10), true, "ctx.isPointInPath(50, 10)", "true");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.html
new file mode 100644
index 0000000000..bccaa842e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.transform.1</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(50, 0);
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.worker.js
new file mode 100644
index 0000000000..0774fd0d62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.transform.1
+// Description:isPointInPath() handles transformations correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(50, 0);
+ ctx.rect(0, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.html
new file mode 100644
index 0000000000..1e587c1d8a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.transform.2</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(50, 0);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.worker.js
new file mode 100644
index 0000000000..ff4c42c450
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.2.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.transform.2
+// Description:isPointInPath() handles transformations correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(50, 0);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.html
new file mode 100644
index 0000000000..826d7e23c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.transform.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.transform.3</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(-1, 1);
+ ctx.rect(-70, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.worker.js
new file mode 100644
index 0000000000..f6750e9109
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.3.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.transform.3
+// Description:isPointInPath() handles transformations correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(-1, 1);
+ ctx.rect(-70, 0, 20, 20);
+ _assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
+ _assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
+ _assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
+ _assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
+ _assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
+ _assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.html
new file mode 100644
index 0000000000..97792d6889
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.transform.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.transform.4</h1>
+<p class="desc">isPointInPath() handles transformations correctly</p>
+
+
+<script>
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(50, 0);
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(0, 50);
+ _assertSame(ctx.isPointInPath(60, 10), false, "ctx.isPointInPath(60, 10)", "false");
+ _assertSame(ctx.isPointInPath(110, 10), true, "ctx.isPointInPath(110, 10)", "true");
+ _assertSame(ctx.isPointInPath(110, 60), false, "ctx.isPointInPath(110, 60)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.worker.js
new file mode 100644
index 0000000000..f43a8a3d1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.transform.4.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.transform.4
+// Description:isPointInPath() handles transformations correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() handles transformations correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.translate(50, 0);
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(0, 50);
+ _assertSame(ctx.isPointInPath(60, 10), false, "ctx.isPointInPath(60, 10)", "false");
+ _assertSame(ctx.isPointInPath(110, 10), true, "ctx.isPointInPath(110, 10)", "true");
+ _assertSame(ctx.isPointInPath(110, 60), false, "ctx.isPointInPath(110, 60)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.html
new file mode 100644
index 0000000000..3920c7de4b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.unclosed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.unclosed</h1>
+<p class="desc">isPointInPath() works on unclosed subpaths</p>
+
+
+<script>
+var t = async_test("isPointInPath() works on unclosed subpaths");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(20, 0);
+ ctx.lineTo(20, 20);
+ ctx.lineTo(0, 20);
+ _assertSame(ctx.isPointInPath(10, 10), true, "ctx.isPointInPath(10, 10)", "true");
+ _assertSame(ctx.isPointInPath(30, 10), false, "ctx.isPointInPath(30, 10)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.worker.js
new file mode 100644
index 0000000000..7b5ffc4a79
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.unclosed.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.unclosed
+// Description:isPointInPath() works on unclosed subpaths
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() works on unclosed subpaths");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(20, 0);
+ ctx.lineTo(20, 20);
+ ctx.lineTo(0, 20);
+ _assertSame(ctx.isPointInPath(10, 10), true, "ctx.isPointInPath(10, 10)", "true");
+ _assertSame(ctx.isPointInPath(30, 10), false, "ctx.isPointInPath(30, 10)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.html
new file mode 100644
index 0000000000..b2741a5069
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInPath.winding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInPath.winding</h1>
+<p class="desc">isPointInPath() uses the non-zero winding number rule</p>
+
+
+<script>
+var t = async_test("isPointInPath() uses the non-zero winding number rule");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Create a square ring, using opposite windings to make a hole in the centre
+ ctx.moveTo(0, 0);
+ ctx.lineTo(50, 0);
+ ctx.lineTo(50, 50);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.lineTo(10, 40);
+ ctx.lineTo(40, 40);
+ ctx.lineTo(40, 10);
+ ctx.lineTo(10, 10);
+
+ _assertSame(ctx.isPointInPath(5, 5), true, "ctx.isPointInPath(5, 5)", "true");
+ _assertSame(ctx.isPointInPath(25, 5), true, "ctx.isPointInPath(25, 5)", "true");
+ _assertSame(ctx.isPointInPath(45, 5), true, "ctx.isPointInPath(45, 5)", "true");
+ _assertSame(ctx.isPointInPath(5, 25), true, "ctx.isPointInPath(5, 25)", "true");
+ _assertSame(ctx.isPointInPath(25, 25), false, "ctx.isPointInPath(25, 25)", "false");
+ _assertSame(ctx.isPointInPath(45, 25), true, "ctx.isPointInPath(45, 25)", "true");
+ _assertSame(ctx.isPointInPath(5, 45), true, "ctx.isPointInPath(5, 45)", "true");
+ _assertSame(ctx.isPointInPath(25, 45), true, "ctx.isPointInPath(25, 45)", "true");
+ _assertSame(ctx.isPointInPath(45, 45), true, "ctx.isPointInPath(45, 45)", "true");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.worker.js
new file mode 100644
index 0000000000..094bc05910
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.winding.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInPath.winding
+// Description:isPointInPath() uses the non-zero winding number rule
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInPath() uses the non-zero winding number rule");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Create a square ring, using opposite windings to make a hole in the centre
+ ctx.moveTo(0, 0);
+ ctx.lineTo(50, 0);
+ ctx.lineTo(50, 50);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.lineTo(10, 40);
+ ctx.lineTo(40, 40);
+ ctx.lineTo(40, 10);
+ ctx.lineTo(10, 10);
+
+ _assertSame(ctx.isPointInPath(5, 5), true, "ctx.isPointInPath(5, 5)", "true");
+ _assertSame(ctx.isPointInPath(25, 5), true, "ctx.isPointInPath(25, 5)", "true");
+ _assertSame(ctx.isPointInPath(45, 5), true, "ctx.isPointInPath(45, 5)", "true");
+ _assertSame(ctx.isPointInPath(5, 25), true, "ctx.isPointInPath(5, 25)", "true");
+ _assertSame(ctx.isPointInPath(25, 25), false, "ctx.isPointInPath(25, 25)", "false");
+ _assertSame(ctx.isPointInPath(45, 25), true, "ctx.isPointInPath(45, 25)", "true");
+ _assertSame(ctx.isPointInPath(5, 45), true, "ctx.isPointInPath(5, 45)", "true");
+ _assertSame(ctx.isPointInPath(25, 45), true, "ctx.isPointInPath(25, 45)", "true");
+ _assertSame(ctx.isPointInPath(45, 45), true, "ctx.isPointInPath(45, 45)", "true");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.html
new file mode 100644
index 0000000000..95f7fd721d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInStroke.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInStroke.basic</h1>
+<p class="desc">detects whether point is in the area contained by the stroke of the path</p>
+
+
+<script>
+var t = async_test("detects whether point is in the area contained by the stroke of the path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+var canvas = new OffscreenCanvas(100, 50);
+var ctx = canvas.getContext('2d');
+
+ctx.strokeStyle = '#0f0';
+ctx.beginPath();
+ctx.rect(0, 0, 20, 20);
+_assertSame(ctx.isPointInStroke(0, 0), true, "ctx.isPointInStroke(0, 0)", "true");
+_assertSame(ctx.isPointInStroke(30, 10), false, "ctx.isPointInStroke(30, 10)", "false");
+
+var path = new Path2D();
+path.rect(20, 20, 100, 100);
+_assertSame(ctx.isPointInStroke(path, 20, 20), true, "ctx.isPointInStroke(path, 20, 20)", "true");
+_assertSame(ctx.isPointInStroke(path, 120, 20), true, "ctx.isPointInStroke(path, 120, 20)", "true");
+t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.worker.js
new file mode 100644
index 0000000000..844f0ef154
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.basic.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInStroke.basic
+// Description:detects whether point is in the area contained by the stroke of the path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("detects whether point is in the area contained by the stroke of the path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+var canvas = new OffscreenCanvas(100, 50);
+var ctx = canvas.getContext('2d');
+
+ctx.strokeStyle = '#0f0';
+ctx.beginPath();
+ctx.rect(0, 0, 20, 20);
+_assertSame(ctx.isPointInStroke(0, 0), true, "ctx.isPointInStroke(0, 0)", "true");
+_assertSame(ctx.isPointInStroke(30, 10), false, "ctx.isPointInStroke(30, 10)", "false");
+
+var path = new Path2D();
+path.rect(20, 20, 100, 100);
+_assertSame(ctx.isPointInStroke(path, 20, 20), true, "ctx.isPointInStroke(path, 20, 20)", "true");
+_assertSame(ctx.isPointInStroke(path, 120, 20), true, "ctx.isPointInStroke(path, 120, 20)", "true");
+t.done();
+
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.html
new file mode 100644
index 0000000000..1ed13b32de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInStroke.scaleddashes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInStroke.scaleddashes</h1>
+<p class="desc">isPointInStroke() should return correct results on dashed paths at high scale factors</p>
+
+
+<script>
+var t = async_test("isPointInStroke() should return correct results on dashed paths at high scale factors");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var scale = 20;
+ ctx.setLineDash([10, 21.4159]); // dash from t=0 to t=10 along the circle
+ ctx.scale(scale, scale);
+ ctx.ellipse(6, 10, 5, 5, 0, 2*Math.PI, false);
+ ctx.stroke();
+
+ // hit-test the beginning of the dash (t=0)
+ _assertSame(ctx.isPointInStroke(11*scale, 10*scale), true, "ctx.isPointInStroke(11*scale, 10*scale)", "true");
+ // hit-test the middle of the dash (t=5)
+ _assertSame(ctx.isPointInStroke(8.70*scale, 14.21*scale), true, "ctx.isPointInStroke(8.70*scale, 14.21*scale)", "true");
+ // hit-test the end of the dash (t=9.8)
+ _assertSame(ctx.isPointInStroke(4.10*scale, 14.63*scale), true, "ctx.isPointInStroke(4.10*scale, 14.63*scale)", "true");
+ // hit-test past the end of the dash (t=10.2)
+ _assertSame(ctx.isPointInStroke(3.74*scale, 14.46*scale), false, "ctx.isPointInStroke(3.74*scale, 14.46*scale)", "false");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.worker.js
new file mode 100644
index 0000000000..240905308e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.scaleddashes.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInStroke.scaleddashes
+// Description:isPointInStroke() should return correct results on dashed paths at high scale factors
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("isPointInStroke() should return correct results on dashed paths at high scale factors");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var scale = 20;
+ ctx.setLineDash([10, 21.4159]); // dash from t=0 to t=10 along the circle
+ ctx.scale(scale, scale);
+ ctx.ellipse(6, 10, 5, 5, 0, 2*Math.PI, false);
+ ctx.stroke();
+
+ // hit-test the beginning of the dash (t=0)
+ _assertSame(ctx.isPointInStroke(11*scale, 10*scale), true, "ctx.isPointInStroke(11*scale, 10*scale)", "true");
+ // hit-test the middle of the dash (t=5)
+ _assertSame(ctx.isPointInStroke(8.70*scale, 14.21*scale), true, "ctx.isPointInStroke(8.70*scale, 14.21*scale)", "true");
+ // hit-test the end of the dash (t=9.8)
+ _assertSame(ctx.isPointInStroke(4.10*scale, 14.63*scale), true, "ctx.isPointInStroke(4.10*scale, 14.63*scale)", "true");
+ // hit-test past the end of the dash (t=10.2)
+ _assertSame(ctx.isPointInStroke(3.74*scale, 14.46*scale), false, "ctx.isPointInStroke(3.74*scale, 14.46*scale)", "false");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.html
new file mode 100644
index 0000000000..0b4c635fc8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInpath.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInpath.invalid</h1>
+<p class="desc">Verify isPointInPath throws exceptions with invalid inputs.</p>
+
+
+<script>
+var t = async_test("Verify isPointInPath throws exceptions with invalid inputs.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ canvas.height = 200;
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ // Testing invalid enumeration isPointInPath (w/ and w/o Path object');
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(path, 50, 50, 'gazonk'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(50, 50, 'gazonk'); });
+
+ // Testing invalid type isPointInPath with Path object');
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, null); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(path, 50, 50, null); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, undefined); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50, 'evenodd'); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.worker.js
new file mode 100644
index 0000000000..f09eeb7526
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.invalid.worker.js
@@ -0,0 +1,46 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInpath.invalid
+// Description:Verify isPointInPath throws exceptions with invalid inputs.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify isPointInPath throws exceptions with invalid inputs.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ canvas.height = 200;
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ // Testing invalid enumeration isPointInPath (w/ and w/o Path object');
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(path, 50, 50, 'gazonk'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(50, 50, 'gazonk'); });
+
+ // Testing invalid type isPointInPath with Path object');
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(null, 50, 50, null); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(path, 50, 50, null); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath(undefined, 50, 50, undefined); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath([], 50, 50, 'evenodd'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50, 'nonzero'); });
+ assert_throws_js(TypeError, function() { ctx.isPointInPath({}, 50, 50, 'evenodd'); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.html
new file mode 100644
index 0000000000..945855231b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.isPointInpath.multi.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.isPointInpath.multi.path</h1>
+<p class="desc">Verify the winding rule in isPointInPath works for path object.</p>
+
+
+<script>
+var t = async_test("Verify the winding rule in isPointInPath works for path object.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(path, 50, 50), true, "ctx.isPointInPath(path, 50, 50)", "true");
+ _assertSame(ctx.isPointInPath(path, 50, 50, undefined), true, "ctx.isPointInPath(path, 50, 50, undefined)", "true");
+ _assertSame(ctx.isPointInPath(path, NaN, 50), false, "ctx.isPointInPath(path, NaN, 50)", "false");
+ _assertSame(ctx.isPointInPath(path, 50, NaN), false, "ctx.isPointInPath(path, 50, NaN)", "false");
+
+ // Testing nonzero isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(path, 50, 50, 'nonzero'), true, "ctx.isPointInPath(path, 50, 50, 'nonzero')", "true");
+
+ // Testing evenodd isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ assert_false(ctx.isPointInPath(path, 50, 50, 'evenodd'));
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.worker.js
new file mode 100644
index 0000000000..d3d4e60747
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.isPointInpath.multi.path.worker.js
@@ -0,0 +1,44 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.isPointInpath.multi.path
+// Description:Verify the winding rule in isPointInPath works for path object.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify the winding rule in isPointInPath works for path object.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(path, 50, 50), true, "ctx.isPointInPath(path, 50, 50)", "true");
+ _assertSame(ctx.isPointInPath(path, 50, 50, undefined), true, "ctx.isPointInPath(path, 50, 50, undefined)", "true");
+ _assertSame(ctx.isPointInPath(path, NaN, 50), false, "ctx.isPointInPath(path, NaN, 50)", "false");
+ _assertSame(ctx.isPointInPath(path, 50, NaN), false, "ctx.isPointInPath(path, 50, NaN)", "false");
+
+ // Testing nonzero isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ _assertSame(ctx.isPointInPath(path, 50, 50, 'nonzero'), true, "ctx.isPointInPath(path, 50, 50, 'nonzero')", "true");
+
+ // Testing evenodd isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ assert_false(ctx.isPointInPath(path, 50, 50, 'evenodd'));
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.html
new file mode 100644
index 0000000000..e0bc64617f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.lineTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.lineTo.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.worker.js
new file mode 100644
index 0000000000..6e02a1f149
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.basic.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.lineTo.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..2561a2f555
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.lineTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.lineTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the point is added and nothing is drawn</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the point is added and nothing is drawn");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.worker.js
new file mode 100644
index 0000000000..ae4d85735e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.lineTo.ensuresubpath.1
+// Description:If there is no subpath, the point is added and nothing is drawn
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the point is added and nothing is drawn");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..9ca14a1393
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.lineTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.lineTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the point is added and used for subsequent drawing</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the point is added and used for subsequent drawing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.worker.js
new file mode 100644
index 0000000000..b6af21235f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.ensuresubpath.2.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.lineTo.ensuresubpath.2
+// Description:If there is no subpath, the point is added and used for subsequent drawing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the point is added and used for subsequent drawing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.html
new file mode 100644
index 0000000000..a649d3a86d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.lineTo.nextpoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.lineTo.nextpoint</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.worker.js
new file mode 100644
index 0000000000..9e4e24a06d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nextpoint.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.lineTo.nextpoint
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.html
new file mode 100644
index 0000000000..35bc80d336
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.lineTo.nonfinite.details</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.lineTo.nonfinite.details</h1>
+<p class="desc">lineTo() with Infinity/NaN for first arg still converts the second arg</p>
+
+
+<script>
+var t = async_test("lineTo() with Infinity/NaN for first arg still converts the second arg");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ for (var arg1 of [Infinity, -Infinity, NaN]) {
+ var converted = false;
+ ctx.lineTo(arg1, { valueOf: function() { converted = true; return 0; } });
+ _assert(converted, "converted");
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.worker.js
new file mode 100644
index 0000000000..5052c74b94
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.details.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.lineTo.nonfinite.details
+// Description:lineTo() with Infinity/NaN for first arg still converts the second arg
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineTo() with Infinity/NaN for first arg still converts the second arg");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ for (var arg1 of [Infinity, -Infinity, NaN]) {
+ var converted = false;
+ ctx.lineTo(arg1, { valueOf: function() { converted = true; return 0; } });
+ _assert(converted, "converted");
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.html
new file mode 100644
index 0000000000..5a144dd7f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.lineTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.lineTo.nonfinite</h1>
+<p class="desc">lineTo() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("lineTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(Infinity, 50);
+ ctx.lineTo(-Infinity, 50);
+ ctx.lineTo(NaN, 50);
+ ctx.lineTo(0, Infinity);
+ ctx.lineTo(0, -Infinity);
+ ctx.lineTo(0, NaN);
+ ctx.lineTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.worker.js
new file mode 100644
index 0000000000..82921b7cd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.lineTo.nonfinite.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.lineTo.nonfinite
+// Description:lineTo() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("lineTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(Infinity, 50);
+ ctx.lineTo(-Infinity, 50);
+ ctx.lineTo(NaN, 50);
+ ctx.lineTo(0, Infinity);
+ ctx.lineTo(0, -Infinity);
+ ctx.lineTo(0, NaN);
+ ctx.lineTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.html
new file mode 100644
index 0000000000..f9777c6ca8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.moveTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.moveTo.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 10, 50);
+ ctx.moveTo(100, 0);
+ ctx.lineTo(10, 0);
+ ctx.lineTo(10, 50);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 90,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.worker.js
new file mode 100644
index 0000000000..0b1df374b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.basic.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.moveTo.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 10, 50);
+ ctx.moveTo(100, 0);
+ ctx.lineTo(10, 0);
+ ctx.lineTo(10, 50);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 90,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.html
new file mode 100644
index 0000000000..0b56cbbfef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.moveTo.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.moveTo.multiple</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 25);
+ ctx.moveTo(100, 25);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.worker.js
new file mode 100644
index 0000000000..9f49ea8a1b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.multiple.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.moveTo.multiple
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 25);
+ ctx.moveTo(100, 25);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.html
new file mode 100644
index 0000000000..c2594c006e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.moveTo.newsubpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.moveTo.newsubpath</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.moveTo(100, 0);
+ ctx.moveTo(100, 50);
+ ctx.moveTo(0, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.worker.js
new file mode 100644
index 0000000000..e3c9c8529d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.newsubpath.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.moveTo.newsubpath
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.moveTo(100, 0);
+ ctx.moveTo(100, 50);
+ ctx.moveTo(0, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.html
new file mode 100644
index 0000000000..ea3eb34c76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.moveTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.moveTo.nonfinite</h1>
+<p class="desc">moveTo() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("moveTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.moveTo(Infinity, 50);
+ ctx.moveTo(-Infinity, 50);
+ ctx.moveTo(NaN, 50);
+ ctx.moveTo(0, Infinity);
+ ctx.moveTo(0, -Infinity);
+ ctx.moveTo(0, NaN);
+ ctx.moveTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.worker.js
new file mode 100644
index 0000000000..97e2bd72e3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.moveTo.nonfinite.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.moveTo.nonfinite
+// Description:moveTo() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("moveTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.moveTo(Infinity, 50);
+ ctx.moveTo(-Infinity, 50);
+ ctx.moveTo(NaN, 50);
+ ctx.moveTo(0, Infinity);
+ ctx.moveTo(0, -Infinity);
+ ctx.moveTo(0, NaN);
+ ctx.moveTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.html
new file mode 100644
index 0000000000..4d14ce5585
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.quadraticCurveTo.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.quadraticCurveTo.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.quadraticCurveTo(100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.worker.js
new file mode 100644
index 0000000000..161e5f1a65
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.basic.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.quadraticCurveTo.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.quadraticCurveTo(100, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html
new file mode 100644
index 0000000000..3e916f00c7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.quadraticCurveTo.ensuresubpath.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.quadraticCurveTo.ensuresubpath.1</h1>
+<p class="desc">If there is no subpath, the first control point is added (and nothing is drawn up to it)</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(100, 50, 200, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 95,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.worker.js
new file mode 100644
index 0000000000..95dcf2bed1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.1.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.quadraticCurveTo.ensuresubpath.1
+// Description:If there is no subpath, the first control point is added (and nothing is drawn up to it)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the first control point is added (and nothing is drawn up to it)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(100, 50, 200, 50);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 95,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html
new file mode 100644
index 0000000000..2fb05a2658
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.quadraticCurveTo.ensuresubpath.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.quadraticCurveTo.ensuresubpath.2</h1>
+<p class="desc">If there is no subpath, the first control point is added</p>
+
+
+<script>
+var t = async_test("If there is no subpath, the first control point is added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(0, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.worker.js
new file mode 100644
index 0000000000..4beaf9dae2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.ensuresubpath.2.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.quadraticCurveTo.ensuresubpath.2
+// Description:If there is no subpath, the first control point is added
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("If there is no subpath, the first control point is added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(0, 25, 100, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.html
new file mode 100644
index 0000000000..ee4f333a08
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.quadraticCurveTo.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.quadraticCurveTo.nonfinite</h1>
+<p class="desc">quadraticCurveTo() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("quadraticCurveTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.quadraticCurveTo(Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(-Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(NaN, 50, 0, 50);
+ ctx.quadraticCurveTo(0, Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, -Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, NaN, 0, 50);
+ ctx.quadraticCurveTo(0, 50, Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, -Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, NaN, 50);
+ ctx.quadraticCurveTo(0, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, -Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, NaN);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.worker.js
new file mode 100644
index 0000000000..a61eb9a8ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.nonfinite.worker.js
@@ -0,0 +1,52 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.quadraticCurveTo.nonfinite
+// Description:quadraticCurveTo() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("quadraticCurveTo() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.quadraticCurveTo(Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(-Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(NaN, 50, 0, 50);
+ ctx.quadraticCurveTo(0, Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, -Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, NaN, 0, 50);
+ ctx.quadraticCurveTo(0, 50, Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, -Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, NaN, 50);
+ ctx.quadraticCurveTo(0, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, -Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, NaN);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.html
new file mode 100644
index 0000000000..92c9377d6f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.quadraticCurveTo.scaled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.quadraticCurveTo.scaled</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-1, 1.05);
+ ctx.quadraticCurveTo(0, -1, 1.2, 1.05);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.worker.js
new file mode 100644
index 0000000000..04fd6e904d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.scaled.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.quadraticCurveTo.scaled
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-1, 1.05);
+ ctx.quadraticCurveTo(0, -1, 1.2, 1.05);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.html
new file mode 100644
index 0000000000..ea42d669cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.quadraticCurveTo.shape</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.quadraticCurveTo.shape</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-1000, 1050);
+ ctx.quadraticCurveTo(0, -1000, 1200, 1050);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.worker.js
new file mode 100644
index 0000000000..9f2afea09d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.quadraticCurveTo.shape.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.quadraticCurveTo.shape
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-1000, 1050);
+ ctx.quadraticCurveTo(0, -1000, 1200, 1050);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.html
new file mode 100644
index 0000000000..e8d874709d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.worker.js
new file mode 100644
index 0000000000..c8eb3838f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.basic.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.html
new file mode 100644
index 0000000000..6f61874390
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.closed</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.rect(100, 50, 100, 100);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.worker.js
new file mode 100644
index 0000000000..f40868730b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.closed.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.closed
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.rect(100, 50, 100, 100);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.html
new file mode 100644
index 0000000000..e4d5ece132
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.end.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.end.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.rect(200, 100, 400, 1000);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.worker.js
new file mode 100644
index 0000000000..fcf9d0526f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.end.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.rect(200, 100, 400, 1000);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.html
new file mode 100644
index 0000000000..d6bad78abb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.end.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.end.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.rect(150, 150, 2000, 2000);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.worker.js
new file mode 100644
index 0000000000..84c1b71d71
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.end.2.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.end.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.rect(150, 150, 2000, 2000);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.html
new file mode 100644
index 0000000000..730e2e887a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.negative</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 50, 25);
+ ctx.rect(100, 0, -50, 25);
+ ctx.rect(0, 50, 50, -25);
+ ctx.rect(100, 50, -50, -25);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.worker.js
new file mode 100644
index 0000000000..44449e85e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.negative.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.negative
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 50, 25);
+ ctx.rect(100, 0, -50, 25);
+ ctx.rect(0, 50, 50, -25);
+ ctx.rect(100, 50, -50, -25);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.html
new file mode 100644
index 0000000000..05b972e045
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.newsubpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.newsubpath</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.rect(200, 25, 1, 1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.worker.js
new file mode 100644
index 0000000000..bdf4a926c1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.newsubpath.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.newsubpath
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.rect(200, 25, 1, 1);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.html
new file mode 100644
index 0000000000..16d76aaf18
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.nonfinite</h1>
+<p class="desc">rect() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("rect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.rect(Infinity, 50, 1, 1);
+ ctx.rect(-Infinity, 50, 1, 1);
+ ctx.rect(NaN, 50, 1, 1);
+ ctx.rect(0, Infinity, 1, 1);
+ ctx.rect(0, -Infinity, 1, 1);
+ ctx.rect(0, NaN, 1, 1);
+ ctx.rect(0, 50, Infinity, 1);
+ ctx.rect(0, 50, -Infinity, 1);
+ ctx.rect(0, 50, NaN, 1);
+ ctx.rect(0, 50, 1, Infinity);
+ ctx.rect(0, 50, 1, -Infinity);
+ ctx.rect(0, 50, 1, NaN);
+ ctx.rect(Infinity, Infinity, 1, 1);
+ ctx.rect(Infinity, Infinity, Infinity, 1);
+ ctx.rect(Infinity, Infinity, Infinity, Infinity);
+ ctx.rect(Infinity, Infinity, 1, Infinity);
+ ctx.rect(Infinity, 50, Infinity, 1);
+ ctx.rect(Infinity, 50, Infinity, Infinity);
+ ctx.rect(Infinity, 50, 1, Infinity);
+ ctx.rect(0, Infinity, Infinity, 1);
+ ctx.rect(0, Infinity, Infinity, Infinity);
+ ctx.rect(0, Infinity, 1, Infinity);
+ ctx.rect(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.worker.js
new file mode 100644
index 0000000000..307a5ec08f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.nonfinite.worker.js
@@ -0,0 +1,52 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.nonfinite
+// Description:rect() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.rect(Infinity, 50, 1, 1);
+ ctx.rect(-Infinity, 50, 1, 1);
+ ctx.rect(NaN, 50, 1, 1);
+ ctx.rect(0, Infinity, 1, 1);
+ ctx.rect(0, -Infinity, 1, 1);
+ ctx.rect(0, NaN, 1, 1);
+ ctx.rect(0, 50, Infinity, 1);
+ ctx.rect(0, 50, -Infinity, 1);
+ ctx.rect(0, 50, NaN, 1);
+ ctx.rect(0, 50, 1, Infinity);
+ ctx.rect(0, 50, 1, -Infinity);
+ ctx.rect(0, 50, 1, NaN);
+ ctx.rect(Infinity, Infinity, 1, 1);
+ ctx.rect(Infinity, Infinity, Infinity, 1);
+ ctx.rect(Infinity, Infinity, Infinity, Infinity);
+ ctx.rect(Infinity, Infinity, 1, Infinity);
+ ctx.rect(Infinity, 50, Infinity, 1);
+ ctx.rect(Infinity, 50, Infinity, Infinity);
+ ctx.rect(Infinity, 50, 1, Infinity);
+ ctx.rect(0, Infinity, Infinity, 1);
+ ctx.rect(0, Infinity, Infinity, Infinity);
+ ctx.rect(0, Infinity, 1, Infinity);
+ ctx.rect(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.html
new file mode 100644
index 0000000000..af97fa6d38
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.selfintersect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.selfintersect</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.rect(45, 20, 10, 10);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.worker.js
new file mode 100644
index 0000000000..495d016e80
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.selfintersect.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.selfintersect
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.rect(45, 20, 10, 10);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.html
new file mode 100644
index 0000000000..a7f79c5223
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.winding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.winding</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.rect(0, 0, 50, 50);
+ ctx.rect(100, 50, -50, -50);
+ ctx.rect(0, 25, 100, -25);
+ ctx.rect(100, 25, -100, 25);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.worker.js
new file mode 100644
index 0000000000..45ff0427e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.winding.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.winding
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.rect(0, 0, 50, 50);
+ ctx.rect(100, 50, -50, -50);
+ ctx.rect(0, 25, 100, -25);
+ ctx.rect(100, 25, -100, 25);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.html
new file mode 100644
index 0000000000..45dac2079d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.zero.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(0, 50, 100, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.worker.js
new file mode 100644
index 0000000000..de6fb58c8a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.zero.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(0, 50, 100, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.html
new file mode 100644
index 0000000000..0386ea06e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.zero.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, -100, 0, 250);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.worker.js
new file mode 100644
index 0000000000..8e323d2dd0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.2.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.zero.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, -100, 0, 250);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.html
new file mode 100644
index 0000000000..1299040929
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.zero.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.zero.3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.worker.js
new file mode 100644
index 0000000000..5e6f490c73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.3.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.zero.3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.html
new file mode 100644
index 0000000000..93da1300de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.zero.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.zero.4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.rect(100, 25, 0, 0);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.worker.js
new file mode 100644
index 0000000000..e19da3b917
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.4.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.zero.4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.rect(100, 25, 0, 0);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.html
new file mode 100644
index 0000000000..45a7f03813
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.zero.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.zero.5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.rect(100, 25, 0, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.worker.js
new file mode 100644
index 0000000000..d39a741573
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.5.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.zero.5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.rect(100, 25, 0, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.html
new file mode 100644
index 0000000000..ac74e20660
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.rect.zero.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.rect.zero.6</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.rect(100, 25, 1000, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.worker.js
new file mode 100644
index 0000000000..a567359c30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.rect.zero.6.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.rect.zero.6
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.rect(100, 25, 1000, 0);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.html
new file mode 100644
index 0000000000..f7e80a0119
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.1.radius.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.1.radius.dompoint</h1>
+<p class="desc">Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.</p>
+
+
+<script>
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html
new file mode 100644
index 0000000000..4ea78c32d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.1.radius.dompoint.single argument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.1.radius.dompoint.single argument</h1>
+<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.</p>
+
+
+<script>
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, new DOMPoint(40, 20));
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.worker.js
new file mode 100644
index 0000000000..b93d88e89c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.single argument.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.1.radius.dompoint.single argument
+// Description:Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, new DOMPoint(40, 20));
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.worker.js
new file mode 100644
index 0000000000..06d787437e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompoint.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.1.radius.dompoint
+// Description:Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.html
new file mode 100644
index 0000000000..97084a446f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.1.radius.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.1.radius.dompointinit</h1>
+<p class="desc">Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.</p>
+
+
+<script>
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html
new file mode 100644
index 0000000000..10c5c14cff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.1.radius.dompointinit.single.argument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.1.radius.dompointinit.single.argument</h1>
+<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.</p>
+
+
+<script>
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, {x: 40, y: 20});
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.worker.js
new file mode 100644
index 0000000000..a62370677b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.single.argument.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.1.radius.dompointinit.single.argument
+// Description:Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, {x: 40, y: 20});
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.worker.js
new file mode 100644
index 0000000000..56c8e1fcef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.dompointinit.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.1.radius.dompointinit
+// Description:Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.html
new file mode 100644
index 0000000000..33574eeaa0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.1.radius.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.1.radius.double</h1>
+<p class="desc">Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.</p>
+
+
+<script>
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.html
new file mode 100644
index 0000000000..b2c826ff38
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.1.radius.double.single.argument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.1.radius.double.single.argument</h1>
+<p class="desc">Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.</p>
+
+
+<script>
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, 20);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.worker.js
new file mode 100644
index 0000000000..04350e81aa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.single.argument.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.1.radius.double.single.argument
+// Description:Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, 20);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.worker.js
new file mode 100644
index 0000000000..ef9da08d61
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.1.radius.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.1.radius.double
+// Description:Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.html
new file mode 100644
index 0000000000..7f67c42ed4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.1.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.2.radii.1.dompoint</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.worker.js
new file mode 100644
index 0000000000..5d0387d0d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompoint.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.1.dompoint
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html
new file mode 100644
index 0000000000..2ac0347d96
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.1.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.2.radii.1.dompointinit</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.worker.js
new file mode 100644
index 0000000000..240a36e846
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.dompointinit.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.1.dompointinit
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.html
new file mode 100644
index 0000000000..791e59ee7e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.1.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.2.radii.1.double</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.worker.js
new file mode 100644
index 0000000000..0fc351c3d6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.1.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.1.double
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.html
new file mode 100644
index 0000000000..d0b085e170
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.2.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.2.radii.2.dompoint</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.worker.js
new file mode 100644
index 0000000000..4c6bb06bdb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompoint.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.2.dompoint
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html
new file mode 100644
index 0000000000..380dd26997
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.2.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.2.radii.2.dompointinit</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.worker.js
new file mode 100644
index 0000000000..e8cdd2c015
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.dompointinit.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.2.dompointinit
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.html
new file mode 100644
index 0000000000..b7b25727b9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.2.radii.2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.2.radii.2.double</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.worker.js
new file mode 100644
index 0000000000..756328682d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.2.radii.2.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.2.radii.2.double
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.html
new file mode 100644
index 0000000000..b7f3e53261
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.1.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.1.dompoint</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.worker.js
new file mode 100644
index 0000000000..9ac4d731c3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompoint.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.1.dompoint
+// Description:Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html
new file mode 100644
index 0000000000..93f89159b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.1.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.1.dompointinit</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.worker.js
new file mode 100644
index 0000000000..9d00729ce9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.dompointinit.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.1.dompointinit
+// Description:Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.html
new file mode 100644
index 0000000000..976458bc5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.1.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.1.double</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.worker.js
new file mode 100644
index 0000000000..c4e1c4fc03
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.1.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.1.double
+// Description:Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.html
new file mode 100644
index 0000000000..1a89c28d15
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.2.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.2.dompoint</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.worker.js
new file mode 100644
index 0000000000..4e4df3a601
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompoint.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.2.dompoint
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html
new file mode 100644
index 0000000000..82ceb6a7bc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.2.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.2.dompointinit</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.worker.js
new file mode 100644
index 0000000000..1333e2386d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.dompointinit.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.2.dompointinit
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.html
new file mode 100644
index 0000000000..b466956d58
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.2.double</h1>
+<p class="desc">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.</p>
+
+
+<script>
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.worker.js
new file mode 100644
index 0000000000..027dbae52a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.2.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.2.double
+// Description: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.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("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.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.html
new file mode 100644
index 0000000000..897aeb2685
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.3.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.3.dompoint</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.worker.js
new file mode 100644
index 0000000000..8a80623fc9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompoint.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.3.dompoint
+// Description:Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html
new file mode 100644
index 0000000000..e1e055cb64
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.3.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.3.dompointinit</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.worker.js
new file mode 100644
index 0000000000..d3b188dd7f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.dompointinit.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.3.dompointinit
+// Description:Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.html
new file mode 100644
index 0000000000..a0e0553364
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.3.radii.3.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.3.radii.3.double</h1>
+<p class="desc">Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.worker.js
new file mode 100644
index 0000000000..177e7c5f6d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.3.radii.3.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.3.radii.3.double
+// Description:Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.html
new file mode 100644
index 0000000000..72e8d6ce33
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.1.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.1.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.worker.js
new file mode 100644
index 0000000000..f27f696f1c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompoint.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.1.dompoint
+// Description:Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html
new file mode 100644
index 0000000000..df6bb11e02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.1.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.1.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.worker.js
new file mode 100644
index 0000000000..2f9d2eb30f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.dompointinit.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.1.dompointinit
+// Description:Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ _assertPixel(canvas, 20,1, 255,0,0,255);
+ _assertPixel(canvas, 41,1, 0,255,0,255);
+ _assertPixel(canvas, 1,10, 255,0,0,255);
+ _assertPixel(canvas, 1,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.html
new file mode 100644
index 0000000000..b669a7bb6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.1.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.1.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.worker.js
new file mode 100644
index 0000000000..9658a39cfb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.1.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.1.double
+// Description:Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.html
new file mode 100644
index 0000000000..b387d88990
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.2.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.2.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.worker.js
new file mode 100644
index 0000000000..83d3f66b3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompoint.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.2.dompoint
+// Description:Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html
new file mode 100644
index 0000000000..76719124e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.2.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.2.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.worker.js
new file mode 100644
index 0000000000..21766040b4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.dompointinit.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.2.dompointinit
+// Description:Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ _assertPixel(canvas, 79,1, 255,0,0,255);
+ _assertPixel(canvas, 58,1, 0,255,0,255);
+ _assertPixel(canvas, 98,10, 255,0,0,255);
+ _assertPixel(canvas, 98,21, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.html
new file mode 100644
index 0000000000..001cb8429c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.2.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.worker.js
new file mode 100644
index 0000000000..b9935a1bd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.2.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.2.double
+// Description:Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.html
new file mode 100644
index 0000000000..5c8c686086
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.3.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.3.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.worker.js
new file mode 100644
index 0000000000..819b1a3986
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompoint.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.3.dompoint
+// Description:Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html
new file mode 100644
index 0000000000..1b94b7d7ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.3.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.3.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.worker.js
new file mode 100644
index 0000000000..e4bd04aa29
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.dompointinit.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.3.dompointinit
+// Description:Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ _assertPixel(canvas, 79,48, 255,0,0,255);
+ _assertPixel(canvas, 58,48, 0,255,0,255);
+ _assertPixel(canvas, 98,39, 255,0,0,255);
+ _assertPixel(canvas, 98,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.html
new file mode 100644
index 0000000000..2a76d2b7b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.3.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.3.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.worker.js
new file mode 100644
index 0000000000..ada627b469
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.3.double
+// Description:Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.html
new file mode 100644
index 0000000000..ce86e45e8b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.4.dompoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.4.dompoint</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.worker.js
new file mode 100644
index 0000000000..770291c6f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompoint.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.4.dompoint
+// Description:Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html
new file mode 100644
index 0000000000..f0ec6c3b99
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.4.dompointinit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.4.dompointinit</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.worker.js
new file mode 100644
index 0000000000..48310c6a30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.dompointinit.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.4.dompointinit
+// Description:Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ _assertPixel(canvas, 20,48, 255,0,0,255);
+ _assertPixel(canvas, 41,48, 0,255,0,255);
+ _assertPixel(canvas, 1,39, 255,0,0,255);
+ _assertPixel(canvas, 1,28, 0,255,0,255);
+
+ // other corners
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.html
new file mode 100644
index 0000000000..6940622cf0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.4.radii.4.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.4.radii.4.double</h1>
+<p class="desc">Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.</p>
+
+
+<script>
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.worker.js
new file mode 100644
index 0000000000..e97ebd98ff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.4.double.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.4.radii.4.double
+// Description:Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.html
new file mode 100644
index 0000000000..97b322971c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.badinput</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.badinput</h1>
+<p class="desc">roundRect() throws or does not throw errors given the strange inputs.</p>
+
+
+<script>
+var t = async_test("roundRect() throws or does not throw errors given the strange inputs.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.roundRect(0, 0, 100, 100, { foo: "bar" }); //=> DOMPointInit
+ ctx.roundRect(0, 0, 100, 100, undefined); //=> "missing" -> 0
+ ctx.roundRect(0, 0, 100, 100, [[]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [[25]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [undefined]); //=> « DOMPointInit »
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, 0n); });
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, { x: 0n }); });
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, [{ x: 0n }]); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.worker.js
new file mode 100644
index 0000000000..461dee89ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.badinput.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.badinput
+// Description:roundRect() throws or does not throw errors given the strange inputs.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("roundRect() throws or does not throw errors given the strange inputs.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.roundRect(0, 0, 100, 100, { foo: "bar" }); //=> DOMPointInit
+ ctx.roundRect(0, 0, 100, 100, undefined); //=> "missing" -> 0
+ ctx.roundRect(0, 0, 100, 100, [[]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [[25]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [undefined]); //=> « DOMPointInit »
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, 0n); });
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, { x: 0n }); });
+ assert_throws_js(TypeError, function() { ctx.roundRect(0, 0, 100, 100, [{ x: 0n }]); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.html
new file mode 100644
index 0000000000..7407ead9cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.closed</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.roundRect(100, 50, 100, 100, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.worker.js
new file mode 100644
index 0000000000..5a9530a683
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.closed.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.closed
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.roundRect(100, 50, 100, 100, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.html
new file mode 100644
index 0000000000..d73b82bee4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.end.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.end.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(200, 100, 400, 1000, [0]);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.worker.js
new file mode 100644
index 0000000000..9428df5bbd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.end.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(200, 100, 400, 1000, [0]);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.html
new file mode 100644
index 0000000000..ce9b44ead1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.end.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.end.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.roundRect(150, 150, 2000, 2000, [0]);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.worker.js
new file mode 100644
index 0000000000..28f1ca1787
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.2.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.end.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.roundRect(150, 150, 2000, 2000, [0]);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.html
new file mode 100644
index 0000000000..72183ecd05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.end.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.end.3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(101, 51, 2000, 2000, [500, 500, 500, 500]);
+ ctx.lineTo(-1, -1);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.worker.js
new file mode 100644
index 0000000000..57cb328cfa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.3.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.end.3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(101, 51, 2000, 2000, [500, 500, 500, 500]);
+ ctx.lineTo(-1, -1);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.html
new file mode 100644
index 0000000000..c4fdee5958
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.end.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.end.4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.roundRect(-1, -1, 2000, 2000, [1000, 1000, 1000, 1000]);
+ ctx.lineTo(-150, -150);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.worker.js
new file mode 100644
index 0000000000..a97a37d157
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.end.4.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.end.4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.roundRect(-1, -1, 2000, 2000, [1000, 1000, 1000, 1000]);
+ ctx.lineTo(-150, -150);
+ ctx.stroke();
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 98,1, 0,255,0,255);
+ _assertPixel(canvas, 1,48, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.html
new file mode 100644
index 0000000000..aa83657244
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.negative</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.roundRect(0, 0, 50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 0, -50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(0, 50, 50, -25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 50, -50, -25, [10, 0, 0, 0]);
+ ctx.fill();
+ // All rects drawn
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ // Correct corners are rounded.
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.worker.js
new file mode 100644
index 0000000000..14459238ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.negative.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.negative
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.roundRect(0, 0, 50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 0, -50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(0, 50, 50, -25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 50, -50, -25, [10, 0, 0, 0]);
+ ctx.fill();
+ // All rects drawn
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ // Correct corners are rounded.
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.html
new file mode 100644
index 0000000000..3ad7e5bb5b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.newsubpath</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.newsubpath</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.roundRect(200, 25, 1, 1, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.worker.js
new file mode 100644
index 0000000000..757327c60d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.newsubpath.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.newsubpath
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.roundRect(200, 25, 1, 1, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.html
new file mode 100644
index 0000000000..adddc7b9b8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.nonfinite</h1>
+<p class="desc">roundRect() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("roundRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.roundRect(Infinity, 50, 1, 1, [0]);
+ ctx.roundRect(-Infinity, 50, 1, 1, [0]);
+ ctx.roundRect(NaN, 50, 1, 1, [0]);
+ ctx.roundRect(0, Infinity, 1, 1, [0]);
+ ctx.roundRect(0, -Infinity, 1, 1, [0]);
+ ctx.roundRect(0, NaN, 1, 1, [0]);
+ ctx.roundRect(0, 50, Infinity, 1, [0]);
+ ctx.roundRect(0, 50, -Infinity, 1, [0]);
+ ctx.roundRect(0, 50, NaN, 1, [0]);
+ ctx.roundRect(0, 50, 1, Infinity, [0]);
+ ctx.roundRect(0, 50, 1, -Infinity, [0]);
+ ctx.roundRect(0, 50, 1, NaN, [0]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,NaN]);
+ ctx.roundRect(Infinity, Infinity, 1, 1, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, 1, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, Infinity, 1, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, 1, Infinity, [0]);
+ ctx.roundRect(Infinity, Infinity, 1, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, 1, 1, [Infinity]);
+ ctx.roundRect(Infinity, 50, Infinity, 1, [0]);
+ ctx.roundRect(Infinity, 50, Infinity, Infinity, [0]);
+ ctx.roundRect(Infinity, 50, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, 50, Infinity, 1, [Infinity]);
+ ctx.roundRect(Infinity, 50, 1, Infinity, [0]);
+ ctx.roundRect(Infinity, 50, 1, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, 50, 1, 1, [Infinity]);
+ ctx.roundRect(0, Infinity, Infinity, 1, [0]);
+ ctx.roundRect(0, Infinity, Infinity, Infinity, [0]);
+ ctx.roundRect(0, Infinity, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(0, Infinity, Infinity, 1, [Infinity]);
+ ctx.roundRect(0, Infinity, 1, Infinity, [0]);
+ ctx.roundRect(0, Infinity, 1, Infinity, [Infinity]);
+ ctx.roundRect(0, Infinity, 1, 1, [Infinity]);
+ ctx.roundRect(0, 50, Infinity, Infinity, [0]);
+ ctx.roundRect(0, 50, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(0, 50, Infinity, 1, [Infinity]);
+ ctx.roundRect(0, 50, 1, Infinity, [Infinity]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, -Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, NaN)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(-Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(NaN, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: -Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: NaN}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: -Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: NaN, y: 10}]);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.worker.js
new file mode 100644
index 0000000000..d6d44d6ffe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.nonfinite.worker.js
@@ -0,0 +1,111 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.nonfinite
+// Description:roundRect() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("roundRect() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.roundRect(Infinity, 50, 1, 1, [0]);
+ ctx.roundRect(-Infinity, 50, 1, 1, [0]);
+ ctx.roundRect(NaN, 50, 1, 1, [0]);
+ ctx.roundRect(0, Infinity, 1, 1, [0]);
+ ctx.roundRect(0, -Infinity, 1, 1, [0]);
+ ctx.roundRect(0, NaN, 1, 1, [0]);
+ ctx.roundRect(0, 50, Infinity, 1, [0]);
+ ctx.roundRect(0, 50, -Infinity, 1, [0]);
+ ctx.roundRect(0, 50, NaN, 1, [0]);
+ ctx.roundRect(0, 50, 1, Infinity, [0]);
+ ctx.roundRect(0, 50, 1, -Infinity, [0]);
+ ctx.roundRect(0, 50, 1, NaN, [0]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,NaN]);
+ ctx.roundRect(0, 50, 1, 1, [Infinity,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [-Infinity,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [NaN,0,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,-Infinity,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,NaN,0,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,-Infinity,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,NaN,0]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,-Infinity]);
+ ctx.roundRect(0, 50, 1, 1, [0,0,0,NaN]);
+ ctx.roundRect(Infinity, Infinity, 1, 1, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, 1, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [0]);
+ ctx.roundRect(Infinity, Infinity, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, Infinity, 1, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, 1, Infinity, [0]);
+ ctx.roundRect(Infinity, Infinity, 1, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, Infinity, 1, 1, [Infinity]);
+ ctx.roundRect(Infinity, 50, Infinity, 1, [0]);
+ ctx.roundRect(Infinity, 50, Infinity, Infinity, [0]);
+ ctx.roundRect(Infinity, 50, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, 50, Infinity, 1, [Infinity]);
+ ctx.roundRect(Infinity, 50, 1, Infinity, [0]);
+ ctx.roundRect(Infinity, 50, 1, Infinity, [Infinity]);
+ ctx.roundRect(Infinity, 50, 1, 1, [Infinity]);
+ ctx.roundRect(0, Infinity, Infinity, 1, [0]);
+ ctx.roundRect(0, Infinity, Infinity, Infinity, [0]);
+ ctx.roundRect(0, Infinity, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(0, Infinity, Infinity, 1, [Infinity]);
+ ctx.roundRect(0, Infinity, 1, Infinity, [0]);
+ ctx.roundRect(0, Infinity, 1, Infinity, [Infinity]);
+ ctx.roundRect(0, Infinity, 1, 1, [Infinity]);
+ ctx.roundRect(0, 50, Infinity, Infinity, [0]);
+ ctx.roundRect(0, 50, Infinity, Infinity, [Infinity]);
+ ctx.roundRect(0, 50, Infinity, 1, [Infinity]);
+ ctx.roundRect(0, 50, 1, Infinity, [Infinity]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, -Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, NaN)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(-Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(NaN, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: -Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: NaN}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: -Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: NaN, y: 10}]);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 90,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.html
new file mode 100644
index 0000000000..db4d871f9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.radius.intersecting.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.radius.intersecting.1</h1>
+<p class="desc">Check that roundRects with intersecting corner arcs are rendered correctly.</p>
+
+
+<script>
+var t = async_test("Check that roundRects with intersecting corner arcs are rendered correctly.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [40, 40, 40, 40]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 2,25, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 97,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.worker.js
new file mode 100644
index 0000000000..27076dbe21
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.1.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.radius.intersecting.1
+// Description:Check that roundRects with intersecting corner arcs are rendered correctly.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that roundRects with intersecting corner arcs are rendered correctly.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [40, 40, 40, 40]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 2,25, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 97,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.html
new file mode 100644
index 0000000000..985942ca36
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.radius.intersecting.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.radius.intersecting.2</h1>
+<p class="desc">Check that roundRects with intersecting corner arcs are rendered correctly.</p>
+
+
+<script>
+var t = async_test("Check that roundRects with intersecting corner arcs are rendered correctly.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [1000, 1000, 1000, 1000]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 2,25, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 97,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.worker.js
new file mode 100644
index 0000000000..5b6de579ae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.intersecting.2.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.radius.intersecting.2
+// Description:Check that roundRects with intersecting corner arcs are rendered correctly.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that roundRects with intersecting corner arcs are rendered correctly.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [1000, 1000, 1000, 1000]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 2,25, 0,255,0,255);
+ _assertPixel(canvas, 50,1, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 50,48, 0,255,0,255);
+ _assertPixel(canvas, 97,25, 0,255,0,255);
+ _assertPixel(canvas, 1,1, 255,0,0,255);
+ _assertPixel(canvas, 98,1, 255,0,0,255);
+ _assertPixel(canvas, 1,48, 255,0,0,255);
+ _assertPixel(canvas, 98,48, 255,0,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html
new file mode 100644
index 0000000000..60a7bebd24
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.radius.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.radius.negative</h1>
+<p class="desc">roundRect() with negative radius throws an exception</p>
+
+
+<script>
+var t = async_test("roundRect() with negative radius throws an exception");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(-1, 1), 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(1, -1)])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: -1, y: 1}, 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: 1, y: -1}])});
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js
new file mode 100644
index 0000000000..554a1ac078
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.radius.negative
+// Description:roundRect() with negative radius throws an exception
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("roundRect() with negative radius throws an exception");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(-1, 1), 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(1, -1)])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: -1, y: 1}, 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: 1, y: -1}])});
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.html
new file mode 100644
index 0000000000..26a69afad0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.radius.noargument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.radius.noargument</h1>
+<p class="desc">Check that roundRect draws a rectangle when no radii are provided.</p>
+
+
+<script>
+var t = async_test("Check that roundRect draws a rectangle when no radii are provided.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(10, 10, 80, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ // upper left corner (10, 10)
+ _assertPixel(canvas, 10,9, 255,0,0,255);
+ _assertPixel(canvas, 9,10, 255,0,0,255);
+ _assertPixel(canvas, 10,10, 0,255,0,255);
+
+ // upper right corner (89, 10)
+ _assertPixel(canvas, 90,10, 255,0,0,255);
+ _assertPixel(canvas, 89,9, 255,0,0,255);
+ _assertPixel(canvas, 89,10, 0,255,0,255);
+
+ // lower right corner (89, 39)
+ _assertPixel(canvas, 89,40, 255,0,0,255);
+ _assertPixel(canvas, 90,39, 255,0,0,255);
+ _assertPixel(canvas, 89,39, 0,255,0,255);
+
+ // lower left corner (10, 30)
+ _assertPixel(canvas, 9,39, 255,0,0,255);
+ _assertPixel(canvas, 10,40, 255,0,0,255);
+ _assertPixel(canvas, 10,39, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.worker.js
new file mode 100644
index 0000000000..1f6227786b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.noargument.worker.js
@@ -0,0 +1,45 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.radius.noargument
+// Description:Check that roundRect draws a rectangle when no radii are provided.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that roundRect draws a rectangle when no radii are provided.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(10, 10, 80, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ // upper left corner (10, 10)
+ _assertPixel(canvas, 10,9, 255,0,0,255);
+ _assertPixel(canvas, 9,10, 255,0,0,255);
+ _assertPixel(canvas, 10,10, 0,255,0,255);
+
+ // upper right corner (89, 10)
+ _assertPixel(canvas, 90,10, 255,0,0,255);
+ _assertPixel(canvas, 89,9, 255,0,0,255);
+ _assertPixel(canvas, 89,10, 0,255,0,255);
+
+ // lower right corner (89, 39)
+ _assertPixel(canvas, 89,40, 255,0,0,255);
+ _assertPixel(canvas, 90,39, 255,0,0,255);
+ _assertPixel(canvas, 89,39, 0,255,0,255);
+
+ // lower left corner (10, 30)
+ _assertPixel(canvas, 9,39, 255,0,0,255);
+ _assertPixel(canvas, 10,40, 255,0,0,255);
+ _assertPixel(canvas, 10,39, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html
new file mode 100644
index 0000000000..763113e438
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.radius.none</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.radius.none</h1>
+<p class="desc">Check that roundRect throws an RangeError if radii is an empty array.</p>
+
+
+<script>
+var t = async_test("Check that roundRect throws an RangeError if radii is an empty array.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])});
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js
new file mode 100644
index 0000000000..fefd1b4dd3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.none.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.radius.none
+// Description:Check that roundRect throws an RangeError if radii is an empty array.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that roundRect throws an RangeError if radii is an empty array.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])});
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html
new file mode 100644
index 0000000000..ce330875fb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.radius.toomany</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.radius.toomany</h1>
+<p class="desc">Check that roundRect throws an IndeSizeError if radii has more than four items.</p>
+
+
+<script>
+var t = async_test("Check that roundRect throws an IndeSizeError if radii has more than four items.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])});
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js
new file mode 100644
index 0000000000..e1250afac7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.radius.toomany.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.radius.toomany
+// Description:Check that roundRect throws an IndeSizeError if radii has more than four items.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Check that roundRect throws an IndeSizeError if radii has more than four items.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])});
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.html
new file mode 100644
index 0000000000..15ee6f4958
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.selfintersect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.selfintersect</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 100, 50, [0]);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.roundRect(45, 20, 10, 10, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.worker.js
new file mode 100644
index 0000000000..91741110fc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.selfintersect.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.selfintersect
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 100, 50, [0]);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.roundRect(45, 20, 10, 10, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.html
new file mode 100644
index 0000000000..47ecd777dc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.winding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.winding</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 50, 50, [0]);
+ ctx.roundRect(100, 50, -50, -50, [0]);
+ ctx.roundRect(0, 25, 100, -25, [0]);
+ ctx.roundRect(100, 25, -100, 25, [0]);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.worker.js
new file mode 100644
index 0000000000..737e99f373
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.winding.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.winding
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 50, 50, [0]);
+ ctx.roundRect(100, 50, -50, -50, [0]);
+ ctx.roundRect(0, 25, 100, -25, [0]);
+ ctx.roundRect(100, 25, -100, 25, [0]);
+ ctx.fill();
+ _assertPixel(canvas, 25,12, 0,255,0,255);
+ _assertPixel(canvas, 75,12, 0,255,0,255);
+ _assertPixel(canvas, 25,37, 0,255,0,255);
+ _assertPixel(canvas, 75,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.html
new file mode 100644
index 0000000000..772339dcc6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.zero.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.zero.1</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(0, 50, 100, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.worker.js
new file mode 100644
index 0000000000..afcaa20769
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.zero.1
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(0, 50, 100, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.html
new file mode 100644
index 0000000000..2aad5aad41
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.zero.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.zero.2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, -100, 0, 250, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.worker.js
new file mode 100644
index 0000000000..dec178bd20
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.2.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.zero.2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, -100, 0, 250, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.html
new file mode 100644
index 0000000000..485384aaff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.zero.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.zero.3</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, 25, 0, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.worker.js
new file mode 100644
index 0000000000..88adb5c437
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.3.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.zero.3
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, 25, 0, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.html
new file mode 100644
index 0000000000..dfd4821a84
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.zero.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.zero.4</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.worker.js
new file mode 100644
index 0000000000..fe8cc149c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.4.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.zero.4
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.html
new file mode 100644
index 0000000000..931a737e3b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.zero.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.zero.5</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.worker.js
new file mode 100644
index 0000000000..1fd61246a9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.5.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.zero.5
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.html
new file mode 100644
index 0000000000..25ed23d329
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.roundrect.zero.6</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.roundrect.zero.6</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.roundRect(100, 25, 1000, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.worker.js
new file mode 100644
index 0000000000..c4b6fba5b0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.zero.6.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.roundrect.zero.6
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.roundRect(100, 25, 1000, 0, [0]);
+ ctx.stroke();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.html
new file mode 100644
index 0000000000..29a95da20d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.empty</h1>
+<p class="desc">Empty subpaths are not stroked</p>
+
+
+<script>
+var t = async_test("Empty subpaths are not stroked");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(40, 25);
+ ctx.moveTo(60, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.worker.js
new file mode 100644
index 0000000000..56ee68f185
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.empty.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.empty
+// Description:Empty subpaths are not stroked
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Empty subpaths are not stroked");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(40, 25);
+ ctx.moveTo(60, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.html
new file mode 100644
index 0000000000..c3847464bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.overlap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.overlap</h1>
+<p class="desc">Stroked subpaths are combined before being drawn</p>
+
+
+<script>
+var t = async_test("Stroked subpaths are combined before being drawn");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 20);
+ ctx.lineTo(100, 20);
+ ctx.moveTo(0, 30);
+ ctx.lineTo(100, 30);
+ ctx.stroke();
+
+ _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.png b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.png
new file mode 100644
index 0000000000..e2a35d48d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.worker.js
new file mode 100644
index 0000000000..0e59d3bfc0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.overlap.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.overlap
+// Description:Stroked subpaths are combined before being drawn
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Stroked subpaths are combined before being drawn");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 20);
+ ctx.lineTo(100, 20);
+ ctx.moveTo(0, 30);
+ ctx.lineTo(100, 30);
+ ctx.stroke();
+
+ _assertPixelApprox(canvas, 50,25, 0,127,0,255, 1);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.html
new file mode 100644
index 0000000000..40a73b85fb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.prune.arc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.prune.arc</h1>
+<p class="desc">Zero-length line segments from arcTo and arc are removed before stroking</p>
+
+
+<script>
+var t = async_test("Zero-length line segments from arcTo and arc are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 150, 25, 10);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(60, 25);
+ ctx.arc(50, 25, 10, 0, 0, false);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.worker.js
new file mode 100644
index 0000000000..880e8146ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.arc.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.prune.arc
+// Description:Zero-length line segments from arcTo and arc are removed before stroking
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Zero-length line segments from arcTo and arc are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 150, 25, 10);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(60, 25);
+ ctx.arc(50, 25, 10, 0, 0, false);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.html
new file mode 100644
index 0000000000..2a3b40068d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.prune.closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.prune.closed</h1>
+<p class="desc">Zero-length line segments from closed paths are removed before stroking</p>
+
+
+<script>
+var t = async_test("Zero-length line segments from closed paths are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.worker.js
new file mode 100644
index 0000000000..e1d271bf6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.closed.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.prune.closed
+// Description:Zero-length line segments from closed paths are removed before stroking
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Zero-length line segments from closed paths are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.closePath();
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.html
new file mode 100644
index 0000000000..45db65d6d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.prune.corner</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.prune.corner</h1>
+<p class="desc">Zero-length line segments are removed before stroking with miters</p>
+
+
+<script>
+var t = async_test("Zero-length line segments are removed before stroking with miters");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.4;
+
+ ctx.beginPath();
+ ctx.moveTo(-1000, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 1000);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.worker.js
new file mode 100644
index 0000000000..fff4ba19e9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.corner.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.prune.corner
+// Description:Zero-length line segments are removed before stroking with miters
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Zero-length line segments are removed before stroking with miters");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.4;
+
+ ctx.beginPath();
+ ctx.moveTo(-1000, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 1000);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.html
new file mode 100644
index 0000000000..946395f1c1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.prune.curve</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.prune.curve</h1>
+<p class="desc">Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking</p>
+
+
+<script>
+var t = async_test("Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.quadraticCurveTo(50, 25, 50, 25);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.worker.js
new file mode 100644
index 0000000000..ed960fdbe7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.curve.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.prune.curve
+// Description:Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.quadraticCurveTo(50, 25, 50, 25);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.html
new file mode 100644
index 0000000000..1f0a892455
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.prune.line</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.prune.line</h1>
+<p class="desc">Zero-length line segments from lineTo are removed before stroking</p>
+
+
+<script>
+var t = async_test("Zero-length line segments from lineTo are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.worker.js
new file mode 100644
index 0000000000..a00e73bcbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.prune.line
+// Description:Zero-length line segments from lineTo are removed before stroking
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Zero-length line segments from lineTo are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.html
new file mode 100644
index 0000000000..ffce538d91
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.prune.rect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.prune.rect</h1>
+<p class="desc">Zero-length line segments from rect and strokeRect are removed before stroking</p>
+
+
+<script>
+var t = async_test("Zero-length line segments from rect and strokeRect are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+
+ ctx.strokeRect(50, 25, 0, 0);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.worker.js
new file mode 100644
index 0000000000..87bb533ff9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.rect.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.prune.rect
+// Description:Zero-length line segments from rect and strokeRect are removed before stroking
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Zero-length line segments from rect and strokeRect are removed before stroking");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+
+ ctx.strokeRect(50, 25, 0, 0);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.html
new file mode 100644
index 0000000000..47639065d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.scale1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.scale1</h1>
+<p class="desc">Stroke line widths are scaled by the current transformation matrix</p>
+
+
+<script>
+var t = async_test("Stroke line widths are scaled by the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.worker.js
new file mode 100644
index 0000000000..3725fdf6e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale1.worker.js
@@ -0,0 +1,49 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.scale1
+// Description:Stroke line widths are scaled by the current transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Stroke line widths are scaled by the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.html
new file mode 100644
index 0000000000..447a6dfadc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.scale2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.scale2</h1>
+<p class="desc">Stroke line widths are scaled by the current transformation matrix</p>
+
+
+<script>
+var t = async_test("Stroke line widths are scaled by the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.worker.js
new file mode 100644
index 0000000000..5223de7816
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.scale2.worker.js
@@ -0,0 +1,51 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.scale2
+// Description:Stroke line widths are scaled by the current transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Stroke line widths are scaled by the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.html
new file mode 100644
index 0000000000..1fb118b122
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.skew</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.skew</h1>
+<p class="desc">Strokes lines are skewed by the current transformation matrix</p>
+
+
+<script>
+var t = async_test("Strokes lines are skewed by the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(49, -50);
+ ctx.lineTo(201, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 283);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.worker.js
new file mode 100644
index 0000000000..e65b796d06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.skew.worker.js
@@ -0,0 +1,65 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.skew
+// Description:Strokes lines are skewed by the current transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Strokes lines are skewed by the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(49, -50);
+ ctx.lineTo(201, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 283);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ _assertPixel(canvas, 0,0, 0,255,0,255);
+ _assertPixel(canvas, 50,0, 0,255,0,255);
+ _assertPixel(canvas, 99,0, 0,255,0,255);
+ _assertPixel(canvas, 0,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 99,25, 0,255,0,255);
+ _assertPixel(canvas, 0,49, 0,255,0,255);
+ _assertPixel(canvas, 50,49, 0,255,0,255);
+ _assertPixel(canvas, 99,49, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.html
new file mode 100644
index 0000000000..3fc9cfad88
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.unaffected</h1>
+<p class="desc">Stroking does not start a new path or subpath</p>
+
+
+<script>
+var t = async_test("Stroking does not start a new path or subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+
+ ctx.closePath();
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.worker.js
new file mode 100644
index 0000000000..d9df1ada94
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.unaffected.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.unaffected
+// Description:Stroking does not start a new path or subpath
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Stroking does not start a new path or subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+
+ ctx.closePath();
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.html
new file mode 100644
index 0000000000..6b980acff2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.stroke.union</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.stroke.union</h1>
+<p class="desc">Strokes in opposite directions are unioned, not subtracted</p>
+
+
+<script>
+var t = async_test("Strokes in opposite directions are unioned, not subtracted");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 40;
+ ctx.moveTo(0, 10);
+ ctx.lineTo(100, 10);
+ ctx.moveTo(100, 40);
+ ctx.lineTo(0, 40);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.worker.js
new file mode 100644
index 0000000000..3b05feec03
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.union.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.stroke.union
+// Description:Strokes in opposite directions are unioned, not subtracted
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Strokes in opposite directions are unioned, not subtracted");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 40;
+ ctx.moveTo(0, 10);
+ ctx.lineTo(100, 10);
+ ctx.moveTo(100, 40);
+ ctx.lineTo(0, 40);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.html
new file mode 100644
index 0000000000..27f00aae03
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.transformation.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.transformation.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-100, 0);
+ ctx.rect(100, 0, 100, 50);
+ ctx.translate(0, -100);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.worker.js
new file mode 100644
index 0000000000..3ae4c876d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.basic.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.transformation.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-100, 0);
+ ctx.rect(100, 0, 100, 50);
+ ctx.translate(0, -100);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.html
new file mode 100644
index 0000000000..786a5cf589
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.transformation.changing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.transformation.changing</h1>
+<p class="desc">Transformations are applied while building paths, not when drawing</p>
+
+
+<script>
+var t = async_test("Transformations are applied while building paths, not when drawing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.translate(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.translate(-100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(1000, 1000);
+ ctx.rotate(Math.PI/2);
+ ctx.scale(0.1, 0.1);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.worker.js
new file mode 100644
index 0000000000..2d8993c685
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.changing.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.transformation.changing
+// Description:Transformations are applied while building paths, not when drawing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Transformations are applied while building paths, not when drawing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.translate(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.translate(-100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(1000, 1000);
+ ctx.rotate(Math.PI/2);
+ ctx.scale(0.1, 0.1);
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.html b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.html
new file mode 100644
index 0000000000..636491bb0e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.path.transformation.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.path.transformation.multiple</h1>
+<p class="desc">Transformations are applied while building paths, not when drawing</p>
+
+
+<script>
+var t = async_test("Transformations are applied while building paths, not when drawing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.translate(-100, 0);
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ ctx.translate(100, 0);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.translate(0, -50);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ ctx.translate(0, 50);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.worker.js b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.worker.js
new file mode 100644
index 0000000000..a9fb37d0de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.transformation.multiple.worker.js
@@ -0,0 +1,42 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.path.transformation.multiple
+// Description:Transformations are applied while building paths, not when drawing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Transformations are applied while building paths, not when drawing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.translate(-100, 0);
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ ctx.translate(100, 0);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.translate(0, -50);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ ctx.translate(0, 50);
+ ctx.stroke();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.html
new file mode 100644
index 0000000000..f6932386df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create1.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create1.basic</h1>
+<p class="desc">createImageData(imgdata) exists and returns something</p>
+
+
+<script>
+var t = async_test("createImageData(imgdata) exists and returns something");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(ctx.createImageData(ctx.createImageData(1, 1)), null, "ctx.createImageData(ctx.createImageData(1, 1))", "null");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.worker.js
new file mode 100644
index 0000000000..30f3ed21b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.basic.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create1.basic
+// Description:createImageData(imgdata) exists and returns something
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(imgdata) exists and returns something");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(ctx.createImageData(ctx.createImageData(1, 1)), null, "ctx.createImageData(ctx.createImageData(1, 1))", "null");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.html
new file mode 100644
index 0000000000..627b09b8bd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create1.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create1.initial</h1>
+<p class="desc">createImageData(imgdata) returns transparent black data of the right size</p>
+
+
+<script>
+var t = async_test("createImageData(imgdata) returns transparent black data of the right size");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata1 = ctx.getImageData(0, 0, 10, 20);
+ var imgdata2 = ctx.createImageData(imgdata1);
+ _assertSame(imgdata2.data.length, imgdata1.data.length, "imgdata2.data.length", "imgdata1.data.length");
+ _assertSame(imgdata2.width, imgdata1.width, "imgdata2.width", "imgdata1.width");
+ _assertSame(imgdata2.height, imgdata1.height, "imgdata2.height", "imgdata1.height");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata2.data.length; ++i)
+ if (imgdata2.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.worker.js
new file mode 100644
index 0000000000..da0856a487
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.initial.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create1.initial
+// Description:createImageData(imgdata) returns transparent black data of the right size
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(imgdata) returns transparent black data of the right size");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata1 = ctx.getImageData(0, 0, 10, 20);
+ var imgdata2 = ctx.createImageData(imgdata1);
+ _assertSame(imgdata2.data.length, imgdata1.data.length, "imgdata2.data.length", "imgdata1.data.length");
+ _assertSame(imgdata2.width, imgdata1.width, "imgdata2.width", "imgdata1.width");
+ _assertSame(imgdata2.height, imgdata1.height, "imgdata2.height", "imgdata1.height");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata2.data.length; ++i)
+ if (imgdata2.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.html
new file mode 100644
index 0000000000..b5a95172b6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create1.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create1.zero</h1>
+<p class="desc">createImageData(null) throws TypeError</p>
+
+
+<script>
+var t = async_test("createImageData(null) throws TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createImageData(null); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.worker.js
new file mode 100644
index 0000000000..1eabd9ebf3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create1.zero.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create1.zero
+// Description:createImageData(null) throws TypeError
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(null) throws TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createImageData(null); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.html
new file mode 100644
index 0000000000..7c265f5209
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.basic</h1>
+<p class="desc">createImageData(sw, sh) exists and returns something</p>
+
+
+<script>
+var t = async_test("createImageData(sw, sh) exists and returns something");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(ctx.createImageData(1, 1), null, "ctx.createImageData(1, 1)", "null");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.worker.js
new file mode 100644
index 0000000000..26ca82929c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.basic.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.basic
+// Description:createImageData(sw, sh) exists and returns something
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(sw, sh) exists and returns something");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(ctx.createImageData(1, 1), null, "ctx.createImageData(1, 1)", "null");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.html
new file mode 100644
index 0000000000..ca54641a30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.double</h1>
+<p class="desc">createImageData(w, h) double is converted to long</p>
+
+
+<script>
+var t = async_test("createImageData(w, h) double is converted to long");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.createImageData(-10.01, -10.99);
+ _assertSame(imgdata1.width, 10, "imgdata1.width", "10");
+ _assertSame(imgdata1.height, 10, "imgdata1.height", "10");
+ _assertSame(imgdata2.width, 10, "imgdata2.width", "10");
+ _assertSame(imgdata2.height, 10, "imgdata2.height", "10");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.worker.js
new file mode 100644
index 0000000000..2f3416d0f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.double.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.double
+// Description:createImageData(w, h) double is converted to long
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(w, h) double is converted to long");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.createImageData(-10.01, -10.99);
+ _assertSame(imgdata1.width, 10, "imgdata1.width", "10");
+ _assertSame(imgdata1.height, 10, "imgdata1.height", "10");
+ _assertSame(imgdata2.width, 10, "imgdata2.width", "10");
+ _assertSame(imgdata2.height, 10, "imgdata2.height", "10");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.html
new file mode 100644
index 0000000000..566a9a30db
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.initial</h1>
+<p class="desc">createImageData(sw, sh) returns transparent black data of the right size</p>
+
+
+<script>
+var t = async_test("createImageData(sw, sh) returns transparent black data of the right size");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.createImageData(10, 20);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ _assert(imgdata.width < imgdata.height, "imgdata.width < imgdata.height");
+ _assert(imgdata.width > 0, "imgdata.width > 0");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; ++i)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.worker.js
new file mode 100644
index 0000000000..472e1dfd2e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.initial.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.initial
+// Description:createImageData(sw, sh) returns transparent black data of the right size
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(sw, sh) returns transparent black data of the right size");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.createImageData(10, 20);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ _assert(imgdata.width < imgdata.height, "imgdata.width < imgdata.height");
+ _assert(imgdata.width > 0, "imgdata.width > 0");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; ++i)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.html
new file mode 100644
index 0000000000..75b8f737fd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.large</h1>
+<p class="desc">createImageData(sw, sh) works for sizes much larger than the canvas</p>
+
+
+<script>
+var t = async_test("createImageData(sw, sh) works for sizes much larger than the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.createImageData(1000, 2000);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ _assert(imgdata.width < imgdata.height, "imgdata.width < imgdata.height");
+ _assert(imgdata.width > 0, "imgdata.width > 0");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; i += 7813) // check ~1024 points (assuming normal scaling)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.worker.js
new file mode 100644
index 0000000000..e2b85bfb69
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.large.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.large
+// Description:createImageData(sw, sh) works for sizes much larger than the canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(sw, sh) works for sizes much larger than the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.createImageData(1000, 2000);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ _assert(imgdata.width < imgdata.height, "imgdata.width < imgdata.height");
+ _assert(imgdata.width > 0, "imgdata.width > 0");
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; i += 7813) // check ~1024 points (assuming normal scaling)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ _assert(isTransparentBlack, "isTransparentBlack");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.html
new file mode 100644
index 0000000000..b41153c282
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.negative</h1>
+<p class="desc">createImageData(sw, sh) takes the absolute magnitude of the size arguments</p>
+
+
+<script>
+var t = async_test("createImageData(sw, sh) takes the absolute magnitude of the size arguments");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.createImageData(10, 20);
+ var imgdata2 = ctx.createImageData(-10, 20);
+ var imgdata3 = ctx.createImageData(10, -20);
+ var imgdata4 = ctx.createImageData(-10, -20);
+ _assertSame(imgdata1.data.length, imgdata2.data.length, "imgdata1.data.length", "imgdata2.data.length");
+ _assertSame(imgdata2.data.length, imgdata3.data.length, "imgdata2.data.length", "imgdata3.data.length");
+ _assertSame(imgdata3.data.length, imgdata4.data.length, "imgdata3.data.length", "imgdata4.data.length");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.worker.js
new file mode 100644
index 0000000000..62ed60e102
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.negative.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.negative
+// Description:createImageData(sw, sh) takes the absolute magnitude of the size arguments
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(sw, sh) takes the absolute magnitude of the size arguments");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.createImageData(10, 20);
+ var imgdata2 = ctx.createImageData(-10, 20);
+ var imgdata3 = ctx.createImageData(10, -20);
+ var imgdata4 = ctx.createImageData(-10, -20);
+ _assertSame(imgdata1.data.length, imgdata2.data.length, "imgdata1.data.length", "imgdata2.data.length");
+ _assertSame(imgdata2.data.length, imgdata3.data.length, "imgdata2.data.length", "imgdata3.data.length");
+ _assertSame(imgdata3.data.length, imgdata4.data.length, "imgdata3.data.length", "imgdata4.data.length");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.html
new file mode 100644
index 0000000000..dd6f6d8350
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.nonfinite</h1>
+<p class="desc">createImageData() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("createImageData() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createImageData(Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(-Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(Infinity, Infinity); });
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ assert_throws_js(TypeError, function() { ctx.createImageData(posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(neginfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(nanobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, neginfobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, nanobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(posinfobj, posinfobj); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.worker.js
new file mode 100644
index 0000000000..18825588bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.nonfinite.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.nonfinite
+// Description:createImageData() throws TypeError if arguments are not finite
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.createImageData(Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(-Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(Infinity, Infinity); });
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ assert_throws_js(TypeError, function() { ctx.createImageData(posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(neginfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(nanobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, neginfobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(10, nanobj); });
+ assert_throws_js(TypeError, function() { ctx.createImageData(posinfobj, posinfobj); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.html
new file mode 100644
index 0000000000..0ecb2fb686
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.round</h1>
+<p class="desc">createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)</p>
+
+
+<script>
+var t = async_test("createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
+ _assertSame(imgdata1.width, imgdata2.width, "imgdata1.width", "imgdata2.width");
+ _assertSame(imgdata1.height, imgdata2.height, "imgdata1.height", "imgdata2.height");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.worker.js
new file mode 100644
index 0000000000..b416a02bf2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.round.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.round
+// Description:createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
+ _assertSame(imgdata1.width, imgdata2.width, "imgdata1.width", "imgdata2.width");
+ _assertSame(imgdata1.height, imgdata2.height, "imgdata1.height", "imgdata2.height");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.html
new file mode 100644
index 0000000000..2f7082a7f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.create2.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.create2.zero</h1>
+<p class="desc">createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero</p>
+
+
+<script>
+var t = async_test("createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0.99, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0.1); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.worker.js
new file mode 100644
index 0000000000..7f57c33898
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.create2.zero.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.create2.zero
+// Description:createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(0.99, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0.1); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.html
new file mode 100644
index 0000000000..d810e64e38
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.basic</h1>
+<p class="desc">getImageData() exists and returns something</p>
+
+
+<script>
+var t = async_test("getImageData() exists and returns something");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(ctx.getImageData(0, 0, 100, 50), null, "ctx.getImageData(0, 0, 100, 50)", "null");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.worker.js
new file mode 100644
index 0000000000..f28268be17
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.basic.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.basic
+// Description:getImageData() exists and returns something
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() exists and returns something");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertDifferent(ctx.getImageData(0, 0, 100, 50), null, "ctx.getImageData(0, 0, 100, 50)", "null");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.html
new file mode 100644
index 0000000000..825d00a5c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.clamp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.clamp</h1>
+<p class="desc">getImageData() clamps colors to the range [0, 255]</p>
+
+
+<script>
+var t = async_test("getImageData() clamps colors to the range [0, 255]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgb(-100, -200, -300)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgb(256, 300, 400)';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata1.data[1], 0, "imgdata1.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata1.data[2], 0, "imgdata1.data[\""+(2)+"\"]", "0");
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ _assertSame(imgdata2.data[0], 255, "imgdata2.data[\""+(0)+"\"]", "255");
+ _assertSame(imgdata2.data[1], 255, "imgdata2.data[\""+(1)+"\"]", "255");
+ _assertSame(imgdata2.data[2], 255, "imgdata2.data[\""+(2)+"\"]", "255");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.worker.js
new file mode 100644
index 0000000000..fb4e76584a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.clamp.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.clamp
+// Description:getImageData() clamps colors to the range [0, 255]
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() clamps colors to the range [0, 255]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgb(-100, -200, -300)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgb(256, 300, 400)';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata1.data[1], 0, "imgdata1.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata1.data[2], 0, "imgdata1.data[\""+(2)+"\"]", "0");
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ _assertSame(imgdata2.data[0], 255, "imgdata2.data[\""+(0)+"\"]", "255");
+ _assertSame(imgdata2.data[1], 255, "imgdata2.data[\""+(1)+"\"]", "255");
+ _assertSame(imgdata2.data[2], 255, "imgdata2.data[\""+(2)+"\"]", "255");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.html
new file mode 100644
index 0000000000..64fc7c7c12
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.double</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.double</h1>
+<p class="desc">createImageData(w, h) double is converted to long</p>
+
+
+<script>
+var t = async_test("createImageData(w, h) double is converted to long");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99);
+ _assertSame(imgdata1.width, 10, "imgdata1.width", "10");
+ _assertSame(imgdata1.height, 10, "imgdata1.height", "10");
+ _assertSame(imgdata2.width, 10, "imgdata2.width", "10");
+ _assertSame(imgdata2.height, 10, "imgdata2.height", "10");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.worker.js
new file mode 100644
index 0000000000..316dce7f80
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.double.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.double
+// Description:createImageData(w, h) double is converted to long
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("createImageData(w, h) double is converted to long");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99);
+ _assertSame(imgdata1.width, 10, "imgdata1.width", "10");
+ _assertSame(imgdata1.height, 10, "imgdata1.height", "10");
+ _assertSame(imgdata2.width, 10, "imgdata2.width", "10");
+ _assertSame(imgdata2.height, 10, "imgdata2.height", "10");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.html
new file mode 100644
index 0000000000..dfc5d106ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.invalid</h1>
+<p class="desc">Verify getImageData() behavior in invalid cases.</p>
+
+
+<script>
+var t = async_test("Verify getImageData() behavior in invalid cases.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ imageData = ctx.getImageData(0,0,2,2);
+ var testValues = [NaN, true, false, "\"garbage\"", "-1",
+ "0", "1", "2", Infinity, -Infinity,
+ -5, -0.5, 0, 0.5, 5,
+ 5.4, 255, 256, null, undefined];
+ var testResults = [0, 1, 0, 0, 0,
+ 0, 1, 2, 255, 0,
+ 0, 0, 0, 0, 5,
+ 5, 255, 255, 0, 0];
+ for (var i = 0; i < testValues.length; i++) {
+ imageData.data[0] = testValues[i];
+ _assert(imageData.data[0] == testResults[i], "imageData.data[\""+(0)+"\"] == testResults[\""+(i)+"\"]");
+ }
+ imageData.data['foo']='garbage';
+ _assert(imageData.data['foo'] == 'garbage', "imageData.data['foo'] == 'garbage'");
+ imageData.data[-1]='garbage';
+ _assert(imageData.data[-1] == undefined, "imageData.data[-1] == undefined");
+ imageData.data[17]='garbage';
+ _assert(imageData.data[17] == undefined, "imageData.data[\""+(17)+"\"] == undefined");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.worker.js
new file mode 100644
index 0000000000..5206899b6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.invalid.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.invalid
+// Description:Verify getImageData() behavior in invalid cases.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Verify getImageData() behavior in invalid cases.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ imageData = ctx.getImageData(0,0,2,2);
+ var testValues = [NaN, true, false, "\"garbage\"", "-1",
+ "0", "1", "2", Infinity, -Infinity,
+ -5, -0.5, 0, 0.5, 5,
+ 5.4, 255, 256, null, undefined];
+ var testResults = [0, 1, 0, 0, 0,
+ 0, 1, 2, 255, 0,
+ 0, 0, 0, 0, 5,
+ 5, 255, 255, 0, 0];
+ for (var i = 0; i < testValues.length; i++) {
+ imageData.data[0] = testValues[i];
+ _assert(imageData.data[0] == testResults[i], "imageData.data[\""+(0)+"\"] == testResults[\""+(i)+"\"]");
+ }
+ imageData.data['foo']='garbage';
+ _assert(imageData.data['foo'] == 'garbage', "imageData.data['foo'] == 'garbage'");
+ imageData.data[-1]='garbage';
+ _assert(imageData.data[-1] == undefined, "imageData.data[-1] == undefined");
+ imageData.data[17]='garbage';
+ _assert(imageData.data[17] == undefined, "imageData.data[\""+(17)+"\"] == undefined");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.html
new file mode 100644
index 0000000000..3e05c3c92b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.large.crash</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.large.crash</h1>
+<p class="desc">Test that canvas crash when image data cannot be allocated.</p>
+
+
+<script>
+var t = async_test("Test that canvas crash when image data cannot be allocated.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 0xffffffff, 2147483647, 10); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.worker.js
new file mode 100644
index 0000000000..62c1771dba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.large.crash.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.large.crash
+// Description:Test that canvas crash when image data cannot be allocated.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test that canvas crash when image data cannot be allocated.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 0xffffffff, 2147483647, 10); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.html
new file mode 100644
index 0000000000..47b5fcd166
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.length</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.length</h1>
+<p class="desc">getImageData() returns a correctly-sized Uint8ClampedArray</p>
+
+
+<script>
+var t = async_test("getImageData() returns a correctly-sized Uint8ClampedArray");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.worker.js
new file mode 100644
index 0000000000..74ed6015f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.length.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.length
+// Description:getImageData() returns a correctly-sized Uint8ClampedArray
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns a correctly-sized Uint8ClampedArray");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.html
new file mode 100644
index 0000000000..62cad61848
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.nonfinite</h1>
+<p class="desc">getImageData() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("getImageData() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(-Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(NaN, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, -Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, NaN, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, Infinity, Infinity); });
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(neginfobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(nanobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, neginfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, nanobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, neginfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, nanobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, neginfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, nanobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, posinfobj, posinfobj); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.worker.js
new file mode 100644
index 0000000000..98b4913a13
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonfinite.worker.js
@@ -0,0 +1,70 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.nonfinite
+// Description:getImageData() throws TypeError if arguments are not finite
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(-Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(NaN, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, -Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, NaN, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, Infinity, Infinity); });
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(neginfobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(nanobj, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, neginfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, nanobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, neginfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, nanobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, neginfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, 10, nanobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, posinfobj, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(posinfobj, 10, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, posinfobj, 10); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, posinfobj, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, posinfobj, 10, posinfobj); });
+ assert_throws_js(TypeError, function() { ctx.getImageData(10, 10, posinfobj, posinfobj); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.html
new file mode 100644
index 0000000000..3a97d9dc05
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.nonpremul</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.nonpremul</h1>
+<p class="desc">getImageData() returns non-premultiplied colors</p>
+
+
+<script>
+var t = async_test("getImageData() returns non-premultiplied colors");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(10, 10, 10, 10);
+ _assert(imgdata.data[0] > 200, "imgdata.data[\""+(0)+"\"] > 200");
+ _assert(imgdata.data[1] > 200, "imgdata.data[\""+(1)+"\"] > 200");
+ _assert(imgdata.data[2] > 200, "imgdata.data[\""+(2)+"\"] > 200");
+ _assert(imgdata.data[3] > 100, "imgdata.data[\""+(3)+"\"] > 100");
+ _assert(imgdata.data[3] < 200, "imgdata.data[\""+(3)+"\"] < 200");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.worker.js
new file mode 100644
index 0000000000..1a8da5efb0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.nonpremul.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.nonpremul
+// Description:getImageData() returns non-premultiplied colors
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns non-premultiplied colors");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(10, 10, 10, 10);
+ _assert(imgdata.data[0] > 200, "imgdata.data[\""+(0)+"\"] > 200");
+ _assert(imgdata.data[1] > 200, "imgdata.data[\""+(1)+"\"] > 200");
+ _assert(imgdata.data[2] > 200, "imgdata.data[\""+(2)+"\"] > 200");
+ _assert(imgdata.data[3] > 100, "imgdata.data[\""+(3)+"\"] > 100");
+ _assert(imgdata.data[3] < 200, "imgdata.data[\""+(3)+"\"] < 200");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.html
new file mode 100644
index 0000000000..04eb67902f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.order.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.order.alpha</h1>
+<p class="desc">getImageData() returns A in the fourth component</p>
+
+
+<script>
+var t = async_test("getImageData() returns A in the fourth component");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assert(imgdata.data[3] < 200, "imgdata.data[\""+(3)+"\"] < 200");
+ _assert(imgdata.data[3] > 100, "imgdata.data[\""+(3)+"\"] > 100");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.worker.js
new file mode 100644
index 0000000000..4338436a6d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.alpha.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.order.alpha
+// Description:getImageData() returns A in the fourth component
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns A in the fourth component");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assert(imgdata.data[3] < 200, "imgdata.data[\""+(3)+"\"] < 200");
+ _assert(imgdata.data[3] > 100, "imgdata.data[\""+(3)+"\"] > 100");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.html
new file mode 100644
index 0000000000..f5b315c60a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.order.cols</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.order.cols</h1>
+<p class="desc">getImageData() returns leftmost columns first</p>
+
+
+<script>
+var t = async_test("getImageData() returns leftmost columns first");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 2, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[Math.round(imgdata.width/2*4)], 255, "imgdata.data[Math.round(imgdata.width/2*4)]", "255");
+ _assertSame(imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)], 0, "imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)]", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.worker.js
new file mode 100644
index 0000000000..6a070e2516
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.cols.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.order.cols
+// Description:getImageData() returns leftmost columns first
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns leftmost columns first");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 2, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[Math.round(imgdata.width/2*4)], 255, "imgdata.data[Math.round(imgdata.width/2*4)]", "255");
+ _assertSame(imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)], 0, "imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)]", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.html
new file mode 100644
index 0000000000..661b437fb1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.order.rgb</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.order.rgb</h1>
+<p class="desc">getImageData() returns R then G then B</p>
+
+
+<script>
+var t = async_test("getImageData() returns R then G then B");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#48c';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0x44, "imgdata.data[\""+(0)+"\"]", "0x44");
+ _assertSame(imgdata.data[1], 0x88, "imgdata.data[\""+(1)+"\"]", "0x88");
+ _assertSame(imgdata.data[2], 0xCC, "imgdata.data[\""+(2)+"\"]", "0xCC");
+ _assertSame(imgdata.data[3], 255, "imgdata.data[\""+(3)+"\"]", "255");
+ _assertSame(imgdata.data[4], 0x44, "imgdata.data[\""+(4)+"\"]", "0x44");
+ _assertSame(imgdata.data[5], 0x88, "imgdata.data[\""+(5)+"\"]", "0x88");
+ _assertSame(imgdata.data[6], 0xCC, "imgdata.data[\""+(6)+"\"]", "0xCC");
+ _assertSame(imgdata.data[7], 255, "imgdata.data[\""+(7)+"\"]", "255");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.worker.js
new file mode 100644
index 0000000000..4e5974f9f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rgb.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.order.rgb
+// Description:getImageData() returns R then G then B
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns R then G then B");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#48c';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0x44, "imgdata.data[\""+(0)+"\"]", "0x44");
+ _assertSame(imgdata.data[1], 0x88, "imgdata.data[\""+(1)+"\"]", "0x88");
+ _assertSame(imgdata.data[2], 0xCC, "imgdata.data[\""+(2)+"\"]", "0xCC");
+ _assertSame(imgdata.data[3], 255, "imgdata.data[\""+(3)+"\"]", "255");
+ _assertSame(imgdata.data[4], 0x44, "imgdata.data[\""+(4)+"\"]", "0x44");
+ _assertSame(imgdata.data[5], 0x88, "imgdata.data[\""+(5)+"\"]", "0x88");
+ _assertSame(imgdata.data[6], 0xCC, "imgdata.data[\""+(6)+"\"]", "0xCC");
+ _assertSame(imgdata.data[7], 255, "imgdata.data[\""+(7)+"\"]", "255");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.html
new file mode 100644
index 0000000000..6d8ee2eba5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.order.rows</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.order.rows</h1>
+<p class="desc">getImageData() returns topmost rows first</p>
+
+
+<script>
+var t = async_test("getImageData() returns topmost rows first");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 2);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[Math.floor(imgdata.width/2*4)], 0, "imgdata.data[Math.floor(imgdata.width/2*4)]", "0");
+ _assertSame(imgdata.data[(imgdata.height/2)*imgdata.width*4], 255, "imgdata.data[(imgdata.height/2)*imgdata.width*4]", "255");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.worker.js
new file mode 100644
index 0000000000..1d3226a503
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.order.rows.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.order.rows
+// Description:getImageData() returns topmost rows first
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns topmost rows first");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 2);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[Math.floor(imgdata.width/2*4)], 0, "imgdata.data[Math.floor(imgdata.width/2*4)]", "0");
+ _assertSame(imgdata.data[(imgdata.height/2)*imgdata.width*4], 255, "imgdata.data[(imgdata.height/2)*imgdata.width*4]", "255");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.html
new file mode 100644
index 0000000000..8db1a42ca1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.range</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.range</h1>
+<p class="desc">getImageData() returns values in the range [0, 255]</p>
+
+
+<script>
+var t = async_test("getImageData() returns values in the range [0, 255]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ _assertSame(imgdata2.data[0], 255, "imgdata2.data[\""+(0)+"\"]", "255");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.worker.js
new file mode 100644
index 0000000000..2e962beeae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.range.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.range
+// Description:getImageData() returns values in the range [0, 255]
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns values in the range [0, 255]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ _assertSame(imgdata2.data[0], 255, "imgdata2.data[\""+(0)+"\"]", "255");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.html
new file mode 100644
index 0000000000..f939ba82df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.rounding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.rounding</h1>
+<p class="desc">Test the handling of non-integer source coordinates in getImageData().</p>
+
+
+<script>
+var t = async_test("Test the handling of non-integer source coordinates in getImageData().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ function testDimensions(sx, sy, sw, sh, width, height)
+ {
+ imageData = ctx.getImageData(sx, sy, sw, sh);
+ _assert(imageData.width == width, "imageData.width == width");
+ _assert(imageData.height == height, "imageData.height == height");
+ }
+
+ testDimensions(0, 0, 20, 10, 20, 10);
+
+ testDimensions(.1, .2, 20, 10, 20, 10);
+ testDimensions(.9, .8, 20, 10, 20, 10);
+
+ testDimensions(0, 0, 20.9, 10.9, 20, 10);
+ testDimensions(0, 0, 20.1, 10.1, 20, 10);
+
+ testDimensions(-1, -1, 20, 10, 20, 10);
+
+ testDimensions(-1.1, 0, 20, 10, 20, 10);
+ testDimensions(-1.9, 0, 20, 10, 20, 10);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.worker.js
new file mode 100644
index 0000000000..b2cd08ade2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.rounding.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.rounding
+// Description:Test the handling of non-integer source coordinates in getImageData().
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Test the handling of non-integer source coordinates in getImageData().");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ function testDimensions(sx, sy, sw, sh, width, height)
+ {
+ imageData = ctx.getImageData(sx, sy, sw, sh);
+ _assert(imageData.width == width, "imageData.width == width");
+ _assert(imageData.height == height, "imageData.height == height");
+ }
+
+ testDimensions(0, 0, 20, 10, 20, 10);
+
+ testDimensions(.1, .2, 20, 10, 20, 10);
+ testDimensions(.9, .8, 20, 10, 20, 10);
+
+ testDimensions(0, 0, 20.9, 10.9, 20, 10);
+ testDimensions(0, 0, 20.1, 10.1, 20, 10);
+
+ testDimensions(-1, -1, 20, 10, 20, 10);
+
+ testDimensions(-1.1, 0, 20, 10, 20, 10);
+ testDimensions(-1.9, 0, 20, 10, 20, 10);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.html
new file mode 100644
index 0000000000..a4b9c7e41c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.source.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.source.negative</h1>
+<p class="desc">getImageData() works with negative width and height, and returns top-to-bottom left-to-right</p>
+
+
+<script>
+var t = async_test("getImageData() works with negative width and height, and returns top-to-bottom left-to-right");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+
+ var imgdata1 = ctx.getImageData(85, 25, -10, -10);
+ _assertSame(imgdata1.data[0], 255, "imgdata1.data[\""+(0)+"\"]", "255");
+ _assertSame(imgdata1.data[1], 255, "imgdata1.data[\""+(1)+"\"]", "255");
+ _assertSame(imgdata1.data[2], 255, "imgdata1.data[\""+(2)+"\"]", "255");
+ _assertSame(imgdata1.data[3], 255, "imgdata1.data[\""+(3)+"\"]", "255");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+0], 0, "imgdata1.data[imgdata1.data.length-4+0]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+1], 0, "imgdata1.data[imgdata1.data.length-4+1]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+2], 0, "imgdata1.data[imgdata1.data.length-4+2]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+3], 255, "imgdata1.data[imgdata1.data.length-4+3]", "255");
+
+ var imgdata2 = ctx.getImageData(0, 0, -1, -1);
+ _assertSame(imgdata2.data[0], 0, "imgdata2.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata2.data[1], 0, "imgdata2.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata2.data[2], 0, "imgdata2.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata2.data[3], 0, "imgdata2.data[\""+(3)+"\"]", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.worker.js
new file mode 100644
index 0000000000..62929918ec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.negative.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.source.negative
+// Description:getImageData() works with negative width and height, and returns top-to-bottom left-to-right
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() works with negative width and height, and returns top-to-bottom left-to-right");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+
+ var imgdata1 = ctx.getImageData(85, 25, -10, -10);
+ _assertSame(imgdata1.data[0], 255, "imgdata1.data[\""+(0)+"\"]", "255");
+ _assertSame(imgdata1.data[1], 255, "imgdata1.data[\""+(1)+"\"]", "255");
+ _assertSame(imgdata1.data[2], 255, "imgdata1.data[\""+(2)+"\"]", "255");
+ _assertSame(imgdata1.data[3], 255, "imgdata1.data[\""+(3)+"\"]", "255");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+0], 0, "imgdata1.data[imgdata1.data.length-4+0]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+1], 0, "imgdata1.data[imgdata1.data.length-4+1]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+2], 0, "imgdata1.data[imgdata1.data.length-4+2]", "0");
+ _assertSame(imgdata1.data[imgdata1.data.length-4+3], 255, "imgdata1.data[imgdata1.data.length-4+3]", "255");
+
+ var imgdata2 = ctx.getImageData(0, 0, -1, -1);
+ _assertSame(imgdata2.data[0], 0, "imgdata2.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata2.data[1], 0, "imgdata2.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata2.data[2], 0, "imgdata2.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata2.data[3], 0, "imgdata2.data[\""+(3)+"\"]", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.html
new file mode 100644
index 0000000000..ca11da80d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.source.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.source.outside</h1>
+<p class="desc">getImageData() returns transparent black outside the canvas</p>
+
+
+<script>
+var t = async_test("getImageData() returns transparent black outside the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#08f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var imgdata1 = ctx.getImageData(-10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata1.data[1], 0, "imgdata1.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata1.data[2], 0, "imgdata1.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata1.data[3], 0, "imgdata1.data[\""+(3)+"\"]", "0");
+
+ var imgdata2 = ctx.getImageData(10, -5, 1, 1);
+ _assertSame(imgdata2.data[0], 0, "imgdata2.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata2.data[1], 0, "imgdata2.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata2.data[2], 0, "imgdata2.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata2.data[3], 0, "imgdata2.data[\""+(3)+"\"]", "0");
+
+ var imgdata3 = ctx.getImageData(200, 5, 1, 1);
+ _assertSame(imgdata3.data[0], 0, "imgdata3.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata3.data[1], 0, "imgdata3.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata3.data[2], 0, "imgdata3.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata3.data[3], 0, "imgdata3.data[\""+(3)+"\"]", "0");
+
+ var imgdata4 = ctx.getImageData(10, 60, 1, 1);
+ _assertSame(imgdata4.data[0], 0, "imgdata4.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata4.data[1], 0, "imgdata4.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata4.data[2], 0, "imgdata4.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata4.data[3], 0, "imgdata4.data[\""+(3)+"\"]", "0");
+
+ var imgdata5 = ctx.getImageData(100, 10, 1, 1);
+ _assertSame(imgdata5.data[0], 0, "imgdata5.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata5.data[1], 0, "imgdata5.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata5.data[2], 0, "imgdata5.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata5.data[3], 0, "imgdata5.data[\""+(3)+"\"]", "0");
+
+ var imgdata6 = ctx.getImageData(0, 10, 1, 1);
+ _assertSame(imgdata6.data[0], 0, "imgdata6.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata6.data[1], 136, "imgdata6.data[\""+(1)+"\"]", "136");
+ _assertSame(imgdata6.data[2], 255, "imgdata6.data[\""+(2)+"\"]", "255");
+ _assertSame(imgdata6.data[3], 255, "imgdata6.data[\""+(3)+"\"]", "255");
+
+ var imgdata7 = ctx.getImageData(-10, 10, 20, 20);
+ _assertSame(imgdata7.data[ 0*4+0], 0, "imgdata7.data[ 0*4+0]", "0");
+ _assertSame(imgdata7.data[ 0*4+1], 0, "imgdata7.data[ 0*4+1]", "0");
+ _assertSame(imgdata7.data[ 0*4+2], 0, "imgdata7.data[ 0*4+2]", "0");
+ _assertSame(imgdata7.data[ 0*4+3], 0, "imgdata7.data[ 0*4+3]", "0");
+ _assertSame(imgdata7.data[ 9*4+0], 0, "imgdata7.data[ 9*4+0]", "0");
+ _assertSame(imgdata7.data[ 9*4+1], 0, "imgdata7.data[ 9*4+1]", "0");
+ _assertSame(imgdata7.data[ 9*4+2], 0, "imgdata7.data[ 9*4+2]", "0");
+ _assertSame(imgdata7.data[ 9*4+3], 0, "imgdata7.data[ 9*4+3]", "0");
+ _assertSame(imgdata7.data[10*4+0], 0, "imgdata7.data[10*4+0]", "0");
+ _assertSame(imgdata7.data[10*4+1], 136, "imgdata7.data[10*4+1]", "136");
+ _assertSame(imgdata7.data[10*4+2], 255, "imgdata7.data[10*4+2]", "255");
+ _assertSame(imgdata7.data[10*4+3], 255, "imgdata7.data[10*4+3]", "255");
+ _assertSame(imgdata7.data[19*4+0], 0, "imgdata7.data[19*4+0]", "0");
+ _assertSame(imgdata7.data[19*4+1], 136, "imgdata7.data[19*4+1]", "136");
+ _assertSame(imgdata7.data[19*4+2], 255, "imgdata7.data[19*4+2]", "255");
+ _assertSame(imgdata7.data[19*4+3], 255, "imgdata7.data[19*4+3]", "255");
+ _assertSame(imgdata7.data[20*4+0], 0, "imgdata7.data[20*4+0]", "0");
+ _assertSame(imgdata7.data[20*4+1], 0, "imgdata7.data[20*4+1]", "0");
+ _assertSame(imgdata7.data[20*4+2], 0, "imgdata7.data[20*4+2]", "0");
+ _assertSame(imgdata7.data[20*4+3], 0, "imgdata7.data[20*4+3]", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.worker.js
new file mode 100644
index 0000000000..35fa83d668
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.worker.js
@@ -0,0 +1,81 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.source.outside
+// Description:getImageData() returns transparent black outside the canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns transparent black outside the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#08f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var imgdata1 = ctx.getImageData(-10, 5, 1, 1);
+ _assertSame(imgdata1.data[0], 0, "imgdata1.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata1.data[1], 0, "imgdata1.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata1.data[2], 0, "imgdata1.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata1.data[3], 0, "imgdata1.data[\""+(3)+"\"]", "0");
+
+ var imgdata2 = ctx.getImageData(10, -5, 1, 1);
+ _assertSame(imgdata2.data[0], 0, "imgdata2.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata2.data[1], 0, "imgdata2.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata2.data[2], 0, "imgdata2.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata2.data[3], 0, "imgdata2.data[\""+(3)+"\"]", "0");
+
+ var imgdata3 = ctx.getImageData(200, 5, 1, 1);
+ _assertSame(imgdata3.data[0], 0, "imgdata3.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata3.data[1], 0, "imgdata3.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata3.data[2], 0, "imgdata3.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata3.data[3], 0, "imgdata3.data[\""+(3)+"\"]", "0");
+
+ var imgdata4 = ctx.getImageData(10, 60, 1, 1);
+ _assertSame(imgdata4.data[0], 0, "imgdata4.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata4.data[1], 0, "imgdata4.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata4.data[2], 0, "imgdata4.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata4.data[3], 0, "imgdata4.data[\""+(3)+"\"]", "0");
+
+ var imgdata5 = ctx.getImageData(100, 10, 1, 1);
+ _assertSame(imgdata5.data[0], 0, "imgdata5.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata5.data[1], 0, "imgdata5.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata5.data[2], 0, "imgdata5.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata5.data[3], 0, "imgdata5.data[\""+(3)+"\"]", "0");
+
+ var imgdata6 = ctx.getImageData(0, 10, 1, 1);
+ _assertSame(imgdata6.data[0], 0, "imgdata6.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata6.data[1], 136, "imgdata6.data[\""+(1)+"\"]", "136");
+ _assertSame(imgdata6.data[2], 255, "imgdata6.data[\""+(2)+"\"]", "255");
+ _assertSame(imgdata6.data[3], 255, "imgdata6.data[\""+(3)+"\"]", "255");
+
+ var imgdata7 = ctx.getImageData(-10, 10, 20, 20);
+ _assertSame(imgdata7.data[ 0*4+0], 0, "imgdata7.data[ 0*4+0]", "0");
+ _assertSame(imgdata7.data[ 0*4+1], 0, "imgdata7.data[ 0*4+1]", "0");
+ _assertSame(imgdata7.data[ 0*4+2], 0, "imgdata7.data[ 0*4+2]", "0");
+ _assertSame(imgdata7.data[ 0*4+3], 0, "imgdata7.data[ 0*4+3]", "0");
+ _assertSame(imgdata7.data[ 9*4+0], 0, "imgdata7.data[ 9*4+0]", "0");
+ _assertSame(imgdata7.data[ 9*4+1], 0, "imgdata7.data[ 9*4+1]", "0");
+ _assertSame(imgdata7.data[ 9*4+2], 0, "imgdata7.data[ 9*4+2]", "0");
+ _assertSame(imgdata7.data[ 9*4+3], 0, "imgdata7.data[ 9*4+3]", "0");
+ _assertSame(imgdata7.data[10*4+0], 0, "imgdata7.data[10*4+0]", "0");
+ _assertSame(imgdata7.data[10*4+1], 136, "imgdata7.data[10*4+1]", "136");
+ _assertSame(imgdata7.data[10*4+2], 255, "imgdata7.data[10*4+2]", "255");
+ _assertSame(imgdata7.data[10*4+3], 255, "imgdata7.data[10*4+3]", "255");
+ _assertSame(imgdata7.data[19*4+0], 0, "imgdata7.data[19*4+0]", "0");
+ _assertSame(imgdata7.data[19*4+1], 136, "imgdata7.data[19*4+1]", "136");
+ _assertSame(imgdata7.data[19*4+2], 255, "imgdata7.data[19*4+2]", "255");
+ _assertSame(imgdata7.data[19*4+3], 255, "imgdata7.data[19*4+3]", "255");
+ _assertSame(imgdata7.data[20*4+0], 0, "imgdata7.data[20*4+0]", "0");
+ _assertSame(imgdata7.data[20*4+1], 0, "imgdata7.data[20*4+1]", "0");
+ _assertSame(imgdata7.data[20*4+2], 0, "imgdata7.data[20*4+2]", "0");
+ _assertSame(imgdata7.data[20*4+3], 0, "imgdata7.data[20*4+3]", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.html
new file mode 100644
index 0000000000..6cb848a718
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.source.size</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.source.size</h1>
+<p class="desc">getImageData() returns bigger ImageData for bigger source rectangle</p>
+
+
+<script>
+var t = async_test("getImageData() returns bigger ImageData for bigger source rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.getImageData(0, 0, 10, 10);
+ var imgdata2 = ctx.getImageData(0, 0, 20, 20);
+ _assert(imgdata2.width > imgdata1.width, "imgdata2.width > imgdata1.width");
+ _assert(imgdata2.height > imgdata1.height, "imgdata2.height > imgdata1.height");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.worker.js
new file mode 100644
index 0000000000..e54d75b97a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.size.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.source.size
+// Description:getImageData() returns bigger ImageData for bigger source rectangle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() returns bigger ImageData for bigger source rectangle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata1 = ctx.getImageData(0, 0, 10, 10);
+ var imgdata2 = ctx.getImageData(0, 0, 20, 20);
+ _assert(imgdata2.width > imgdata1.width, "imgdata2.width > imgdata1.width");
+ _assert(imgdata2.height > imgdata1.height, "imgdata2.height > imgdata1.height");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.html
new file mode 100644
index 0000000000..66a0b80fd7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.unaffected</h1>
+<p class="desc">getImageData() is not affected by context state</p>
+
+
+<script>
+var t = async_test("getImageData() is not affected by context state");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50)
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.rect(0, 0, 5, 5);
+ ctx.clip();
+ var imgdata = ctx.getImageData(0, 0, 50, 50);
+ ctx.restore();
+ ctx.putImageData(imgdata, 50, 0);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.worker.js
new file mode 100644
index 0000000000..8bf0dddb06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.unaffected.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.unaffected
+// Description:getImageData() is not affected by context state
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() is not affected by context state");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50)
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.rect(0, 0, 5, 5);
+ ctx.clip();
+ var imgdata = ctx.getImageData(0, 0, 50, 50);
+ ctx.restore();
+ ctx.putImageData(imgdata, 50, 0);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.html
new file mode 100644
index 0000000000..042a8bc5f5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.get.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.get.zero</h1>
+<p class="desc">getImageData() throws INDEX_SIZE_ERR if size is zero</p>
+
+
+<script>
+var t = async_test("getImageData() throws INDEX_SIZE_ERR if size is zero");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0.1, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0.99); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, -0.1, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, -0.99); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.worker.js
new file mode 100644
index 0000000000..ed31030d3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.zero.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.get.zero
+// Description:getImageData() throws INDEX_SIZE_ERR if size is zero
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("getImageData() throws INDEX_SIZE_ERR if size is zero");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 0); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0.1, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0.99); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, -0.1, 10); });
+ assert_throws_dom("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, -0.99); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.html
new file mode 100644
index 0000000000..aa6073eedf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.clamp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.clamp</h1>
+<p class="desc">ImageData.data clamps numbers to [0, 255]</p>
+
+
+<script>
+var t = async_test("ImageData.data clamps numbers to [0, 255]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 300;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -100;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 200+Math.pow(2, 32);
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -200-Math.pow(2, 32);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Math.pow(10, 39);
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Math.pow(10, 39);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Infinity;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Infinity;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.worker.js
new file mode 100644
index 0000000000..260198fe2f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.clamp.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.clamp
+// Description:ImageData.data clamps numbers to [0, 255]
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData.data clamps numbers to [0, 255]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 300;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -100;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 200+Math.pow(2, 32);
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -200-Math.pow(2, 32);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Math.pow(10, 39);
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Math.pow(10, 39);
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Infinity;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Infinity;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.html
new file mode 100644
index 0000000000..af692a7f9f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.nan</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.nan</h1>
+<p class="desc">ImageData.data converts NaN to 0</p>
+
+
+<script>
+var t = async_test("ImageData.data converts NaN to 0");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = NaN;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "cheese";
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.worker.js
new file mode 100644
index 0000000000..4ebfedb1e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.nan.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.nan
+// Description:ImageData.data converts NaN to 0
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData.data converts NaN to 0");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = NaN;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "cheese";
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.html
new file mode 100644
index 0000000000..68a6f63868
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.properties</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.properties</h1>
+<p class="desc">ImageData objects have the right properties</p>
+
+
+<script>
+var t = async_test("ImageData objects have the right properties");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(typeof(imgdata.width), 'number', "typeof(imgdata.width)", "'number'");
+ _assertSame(typeof(imgdata.height), 'number', "typeof(imgdata.height)", "'number'");
+ _assertSame(typeof(imgdata.data), 'object', "typeof(imgdata.data)", "'object'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.worker.js
new file mode 100644
index 0000000000..e428e0d4fc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.properties
+// Description:ImageData objects have the right properties
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData objects have the right properties");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ _assertSame(typeof(imgdata.width), 'number', "typeof(imgdata.width)", "'number'");
+ _assertSame(typeof(imgdata.height), 'number', "typeof(imgdata.height)", "'number'");
+ _assertSame(typeof(imgdata.data), 'object', "typeof(imgdata.data)", "'object'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.html
new file mode 100644
index 0000000000..2ab5f47f64
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.readonly</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.readonly</h1>
+<p class="desc">ImageData objects properties are read-only</p>
+
+
+<script>
+var t = async_test("ImageData objects properties are read-only");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ var w = imgdata.width;
+ var h = imgdata.height;
+ var d = imgdata.data;
+ imgdata.width = 123;
+ imgdata.height = 123;
+ imgdata.data = [100,100,100,100];
+ _assertSame(imgdata.width, w, "imgdata.width", "w");
+ _assertSame(imgdata.height, h, "imgdata.height", "h");
+ _assertSame(imgdata.data, d, "imgdata.data", "d");
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[1], 0, "imgdata.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata.data[2], 0, "imgdata.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata.data[3], 0, "imgdata.data[\""+(3)+"\"]", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.worker.js
new file mode 100644
index 0000000000..d02f0f319a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.readonly.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.readonly
+// Description:ImageData objects properties are read-only
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData objects properties are read-only");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ var w = imgdata.width;
+ var h = imgdata.height;
+ var d = imgdata.data;
+ imgdata.width = 123;
+ imgdata.height = 123;
+ imgdata.data = [100,100,100,100];
+ _assertSame(imgdata.width, w, "imgdata.width", "w");
+ _assertSame(imgdata.height, h, "imgdata.height", "h");
+ _assertSame(imgdata.data, d, "imgdata.data", "d");
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ _assertSame(imgdata.data[1], 0, "imgdata.data[\""+(1)+"\"]", "0");
+ _assertSame(imgdata.data[2], 0, "imgdata.data[\""+(2)+"\"]", "0");
+ _assertSame(imgdata.data[3], 0, "imgdata.data[\""+(3)+"\"]", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.html
new file mode 100644
index 0000000000..fbde0cd940
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.round</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.round</h1>
+<p class="desc">ImageData.data rounds numbers with round-to-zero</p>
+
+
+<script>
+var t = async_test("ImageData.data rounds numbers with round-to-zero");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 0.499;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 0.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 0.501;
+ _assertSame(imgdata.data[0], 1, "imgdata.data[\""+(0)+"\"]", "1");
+ imgdata.data[0] = 1.499;
+ _assertSame(imgdata.data[0], 1, "imgdata.data[\""+(0)+"\"]", "1");
+ imgdata.data[0] = 1.5;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 1.501;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 2.5;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 3.5;
+ _assertSame(imgdata.data[0], 4, "imgdata.data[\""+(0)+"\"]", "4");
+ imgdata.data[0] = 252.5;
+ _assertSame(imgdata.data[0], 252, "imgdata.data[\""+(0)+"\"]", "252");
+ imgdata.data[0] = 253.5;
+ _assertSame(imgdata.data[0], 254, "imgdata.data[\""+(0)+"\"]", "254");
+ imgdata.data[0] = 254.5;
+ _assertSame(imgdata.data[0], 254, "imgdata.data[\""+(0)+"\"]", "254");
+ imgdata.data[0] = 256.5;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = -0.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = -1.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.worker.js
new file mode 100644
index 0000000000..8ef3c02793
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.round.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.round
+// Description:ImageData.data rounds numbers with round-to-zero
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData.data rounds numbers with round-to-zero");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 0.499;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 0.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = 0.501;
+ _assertSame(imgdata.data[0], 1, "imgdata.data[\""+(0)+"\"]", "1");
+ imgdata.data[0] = 1.499;
+ _assertSame(imgdata.data[0], 1, "imgdata.data[\""+(0)+"\"]", "1");
+ imgdata.data[0] = 1.5;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 1.501;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 2.5;
+ _assertSame(imgdata.data[0], 2, "imgdata.data[\""+(0)+"\"]", "2");
+ imgdata.data[0] = 3.5;
+ _assertSame(imgdata.data[0], 4, "imgdata.data[\""+(0)+"\"]", "4");
+ imgdata.data[0] = 252.5;
+ _assertSame(imgdata.data[0], 252, "imgdata.data[\""+(0)+"\"]", "252");
+ imgdata.data[0] = 253.5;
+ _assertSame(imgdata.data[0], 254, "imgdata.data[\""+(0)+"\"]", "254");
+ imgdata.data[0] = 254.5;
+ _assertSame(imgdata.data[0], 254, "imgdata.data[\""+(0)+"\"]", "254");
+ imgdata.data[0] = 256.5;
+ _assertSame(imgdata.data[0], 255, "imgdata.data[\""+(0)+"\"]", "255");
+ imgdata.data[0] = -0.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ imgdata.data[0] = -1.5;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.html
new file mode 100644
index 0000000000..27ed5a3504
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.set</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.set</h1>
+<p class="desc">ImageData.data can be modified</p>
+
+
+<script>
+var t = async_test("ImageData.data can be modified");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ _assertSame(imgdata.data[0], 100, "imgdata.data[\""+(0)+"\"]", "100");
+ imgdata.data[0] = 200;
+ _assertSame(imgdata.data[0], 200, "imgdata.data[\""+(0)+"\"]", "200");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.worker.js
new file mode 100644
index 0000000000..f9b755f7e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.set.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.set
+// Description:ImageData.data can be modified
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData.data can be modified");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ _assertSame(imgdata.data[0], 100, "imgdata.data[\""+(0)+"\"]", "100");
+ imgdata.data[0] = 200;
+ _assertSame(imgdata.data[0], 200, "imgdata.data[\""+(0)+"\"]", "200");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.html
new file mode 100644
index 0000000000..a437c475a5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.string</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.string</h1>
+<p class="desc">ImageData.data converts strings to numbers with ToNumber</p>
+
+
+<script>
+var t = async_test("ImageData.data converts strings to numbers with ToNumber");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "110";
+ _assertSame(imgdata.data[0], 110, "imgdata.data[\""+(0)+"\"]", "110");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "0x78";
+ _assertSame(imgdata.data[0], 120, "imgdata.data[\""+(0)+"\"]", "120");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = " +130e0 ";
+ _assertSame(imgdata.data[0], 130, "imgdata.data[\""+(0)+"\"]", "130");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.worker.js
new file mode 100644
index 0000000000..84cff6a48c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.string.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.string
+// Description:ImageData.data converts strings to numbers with ToNumber
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData.data converts strings to numbers with ToNumber");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "110";
+ _assertSame(imgdata.data[0], 110, "imgdata.data[\""+(0)+"\"]", "110");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "0x78";
+ _assertSame(imgdata.data[0], 120, "imgdata.data[\""+(0)+"\"]", "120");
+ imgdata.data[0] = 100;
+ imgdata.data[0] = " +130e0 ";
+ _assertSame(imgdata.data[0], 130, "imgdata.data[\""+(0)+"\"]", "130");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.html
new file mode 100644
index 0000000000..81462339e9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.object.undefined</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.object.undefined</h1>
+<p class="desc">ImageData.data converts undefined to 0</p>
+
+
+<script>
+var t = async_test("ImageData.data converts undefined to 0");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = undefined;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.worker.js
new file mode 100644
index 0000000000..825f8c102f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.object.undefined.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.object.undefined
+// Description:ImageData.data converts undefined to 0
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("ImageData.data converts undefined to 0");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = undefined;
+ _assertSame(imgdata.data[0], 0, "imgdata.data[\""+(0)+"\"]", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.html
new file mode 100644
index 0000000000..dcd2d92ab1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.alpha</h1>
+<p class="desc">putImageData() puts non-solid image data correctly</p>
+
+
+<script>
+var t = async_test("putImageData() puts non-solid image data correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.25)';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,64, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.png b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.png
new file mode 100644
index 0000000000..5428c65524
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.worker.js
new file mode 100644
index 0000000000..25d8047189
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.alpha.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.alpha
+// Description:putImageData() puts non-solid image data correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() puts non-solid image data correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.25)';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,64, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.html
new file mode 100644
index 0000000000..257e0330d5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.basic</h1>
+<p class="desc">putImageData() puts image data from getImageData() onto the canvas</p>
+
+
+<script>
+var t = async_test("putImageData() puts image data from getImageData() onto the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.worker.js
new file mode 100644
index 0000000000..6a68ffa792
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.basic
+// Description:putImageData() puts image data from getImageData() onto the canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() puts image data from getImageData() onto the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.html
new file mode 100644
index 0000000000..648ded588c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.clip</h1>
+<p class="desc">putImageData() is not affected by clipping regions</p>
+
+
+<script>
+var t = async_test("putImageData() is not affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.worker.js
new file mode 100644
index 0000000000..b665edbb33
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.clip.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.clip
+// Description:putImageData() is not affected by clipping regions
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() is not affected by clipping regions");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.html
new file mode 100644
index 0000000000..08f35117dd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.created</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.created</h1>
+<p class="desc">putImageData() puts image data from createImageData() onto the canvas</p>
+
+
+<script>
+var t = async_test("putImageData() puts image data from createImageData() onto the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.createImageData(100, 50);
+ for (var i = 0; i < imgdata.data.length; i += 4) {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ imgdata.data[i+2] = 0;
+ imgdata.data[i+3] = 255;
+ }
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.worker.js
new file mode 100644
index 0000000000..f249efb4bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.created.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.created
+// Description:putImageData() puts image data from createImageData() onto the canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() puts image data from createImageData() onto the canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.createImageData(100, 50);
+ for (var i = 0; i < imgdata.data.length; i += 4) {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ imgdata.data[i+2] = 0;
+ imgdata.data[i+3] = 255;
+ }
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.html
new file mode 100644
index 0000000000..cddd0451a4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.cross</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.cross</h1>
+<p class="desc">putImageData() accepts image data got from a different canvas</p>
+
+
+<script>
+var t = async_test("putImageData() accepts image data got from a different canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50)
+ var imgdata = ctx2.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.worker.js
new file mode 100644
index 0000000000..0ec4ed142f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.cross.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.cross
+// Description:putImageData() accepts image data got from a different canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() accepts image data got from a different canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50)
+ var imgdata = ctx2.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.html
new file mode 100644
index 0000000000..cea4d0d477
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.dirty.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.dirty.negative</h1>
+<p class="desc">putImageData() handles negative-sized dirty rectangles correctly</p>
+
+
+<script>
+var t = async_test("putImageData() handles negative-sized dirty rectangles correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 20, 20, -20, -20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.worker.js
new file mode 100644
index 0000000000..0a7af64049
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.negative.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.dirty.negative
+// Description:putImageData() handles negative-sized dirty rectangles correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() handles negative-sized dirty rectangles correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 20, 20, -20, -20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.html
new file mode 100644
index 0000000000..7b67ef2253
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.dirty.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.dirty.outside</h1>
+<p class="desc">putImageData() handles dirty rectangles outside the canvas correctly</p>
+
+
+<script>
+var t = async_test("putImageData() handles dirty rectangles outside the canvas correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+
+ ctx.putImageData(imgdata, 100, 20, 20, 20, -20, -20);
+ ctx.putImageData(imgdata, 200, 200, 0, 0, 100, 50);
+ ctx.putImageData(imgdata, 40, 20, -30, -20, 30, 20);
+ ctx.putImageData(imgdata, -30, 20, 0, 0, 30, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,45, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.worker.js
new file mode 100644
index 0000000000..87b88a09f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.outside.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.dirty.outside
+// Description:putImageData() handles dirty rectangles outside the canvas correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() handles dirty rectangles outside the canvas correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+
+ ctx.putImageData(imgdata, 100, 20, 20, 20, -20, -20);
+ ctx.putImageData(imgdata, 200, 200, 0, 0, 100, 50);
+ ctx.putImageData(imgdata, 40, 20, -30, -20, 30, 20);
+ ctx.putImageData(imgdata, -30, 20, 0, 0, 30, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 98,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 1,45, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.html
new file mode 100644
index 0000000000..9f571427a8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.dirty.rect1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.dirty.rect1</h1>
+<p class="desc">putImageData() only modifies areas inside the dirty rectangle, using width and height</p>
+
+
+<script>
+var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using width and height");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 0, 0, 20, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.worker.js
new file mode 100644
index 0000000000..6feea9556d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect1.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.dirty.rect1
+// Description:putImageData() only modifies areas inside the dirty rectangle, using width and height
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using width and height");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 0, 0, 20, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.html
new file mode 100644
index 0000000000..997c1136a1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.dirty.rect2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.dirty.rect2</h1>
+<p class="desc">putImageData() only modifies areas inside the dirty rectangle, using x and y</p>
+
+
+<script>
+var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using x and y");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(60, 30, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, -20, -10, 60, 30, 20, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.worker.js
new file mode 100644
index 0000000000..752a3cdf1e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.rect2.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.dirty.rect2
+// Description:putImageData() only modifies areas inside the dirty rectangle, using x and y
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using x and y");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(60, 30, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, -20, -10, 60, 30, 20, 20);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.html
new file mode 100644
index 0000000000..fb90a017e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.dirty.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.dirty.zero</h1>
+<p class="desc">putImageData() with zero-sized dirty rectangle puts nothing</p>
+
+
+<script>
+var t = async_test("putImageData() with zero-sized dirty rectangle puts nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.worker.js
new file mode 100644
index 0000000000..2fa474c07f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.dirty.zero.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.dirty.zero
+// Description:putImageData() with zero-sized dirty rectangle puts nothing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() with zero-sized dirty rectangle puts nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.html
new file mode 100644
index 0000000000..337701aaf5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.modified</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.modified</h1>
+<p class="desc">putImageData() puts modified image data correctly</p>
+
+
+<script>
+var t = async_test("putImageData() puts modified image data correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(45, 20, 10, 10)
+ var imgdata = ctx.getImageData(45, 20, 10, 10);
+ for (var i = 0, len = imgdata.width*imgdata.height*4; i < len; i += 4)
+ {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ }
+ ctx.putImageData(imgdata, 45, 20);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.worker.js
new file mode 100644
index 0000000000..846a9dbc2d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.modified.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.modified
+// Description:putImageData() puts modified image data correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() puts modified image data correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(45, 20, 10, 10)
+ var imgdata = ctx.getImageData(45, 20, 10, 10);
+ for (var i = 0, len = imgdata.width*imgdata.height*4; i < len; i += 4)
+ {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ }
+ ctx.putImageData(imgdata, 45, 20);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.html
new file mode 100644
index 0000000000..eb61d38e9e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.nonfinite</h1>
+<p class="desc">putImageData() throws TypeError if arguments are not finite</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("putImageData() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, -Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, NaN, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, -Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, NaN, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, Infinity); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.worker.js
new file mode 100644
index 0000000000..479ad69467
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.nonfinite.worker.js
@@ -0,0 +1,104 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.nonfinite
+// Description:putImageData() throws TypeError if arguments are not finite
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() throws TypeError if arguments are not finite");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, -Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, NaN, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, -Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, NaN, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, -Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, NaN, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, -Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, NaN); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, 10); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, Infinity); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, Infinity); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.html
new file mode 100644
index 0000000000..89fe06686d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.null</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.null</h1>
+<p class="desc">putImageData() with null imagedata throws TypeError</p>
+
+
+<script>
+var t = async_test("putImageData() with null imagedata throws TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.putImageData(null, 0, 0); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.worker.js
new file mode 100644
index 0000000000..2f021b638e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.null.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.null
+// Description:putImageData() with null imagedata throws TypeError
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() with null imagedata throws TypeError");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ assert_throws_js(TypeError, function() { ctx.putImageData(null, 0, 0); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.html
new file mode 100644
index 0000000000..6c32376006
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.path</h1>
+<p class="desc">putImageData() does not affect the current path</p>
+
+
+<script>
+var t = async_test("putImageData() does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.rect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.putImageData(imgdata, 0, 0);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.worker.js
new file mode 100644
index 0000000000..66781a922d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.path.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.path
+// Description:putImageData() does not affect the current path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.rect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.putImageData(imgdata, 0, 0);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.html
new file mode 100644
index 0000000000..3d3e99b135
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.unaffected</h1>
+<p class="desc">putImageData() is not affected by context state</p>
+
+
+<script>
+var t = async_test("putImageData() is not affected by context state");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.translate(100, 50);
+ ctx.scale(0.1, 0.1);
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.worker.js
new file mode 100644
index 0000000000..75adb865ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unaffected.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.unaffected
+// Description:putImageData() is not affected by context state
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() is not affected by context state");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.translate(100, 50);
+ ctx.scale(0.1, 0.1);
+ ctx.putImageData(imgdata, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.html
new file mode 100644
index 0000000000..d78fa4e035
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.unchanged</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.unchanged</h1>
+<p class="desc">putImageData(getImageData(...), ...) has no effect</p>
+
+
+<script>
+var t = async_test("putImageData(getImageData(...), ...) has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var i = 0;
+ for (var y = 0; y < 16; ++y) {
+ for (var x = 0; x < 16; ++x, ++i) {
+ ctx.fillStyle = 'rgba(' + i + ',' + (Math.floor(i*1.5) % 256) + ',' + (Math.floor(i*23.3) % 256) + ',' + (i/256) + ')';
+ ctx.fillRect(x, y, 1, 1);
+ }
+ }
+ var imgdata1 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ var olddata = [];
+ for (var i = 0; i < imgdata1.data.length; ++i)
+ olddata[i] = imgdata1.data[i];
+
+ ctx.putImageData(imgdata1, 0.1, 0.2);
+
+ var imgdata2 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ for (var i = 0; i < imgdata2.data.length; ++i) {
+ _assertSame(olddata[i], imgdata2.data[i], "olddata[\""+(i)+"\"]", "imgdata2.data[\""+(i)+"\"]");
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.worker.js
new file mode 100644
index 0000000000..5e9362fab2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.unchanged.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.unchanged
+// Description:putImageData(getImageData(...), ...) has no effect
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData(getImageData(...), ...) has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var i = 0;
+ for (var y = 0; y < 16; ++y) {
+ for (var x = 0; x < 16; ++x, ++i) {
+ ctx.fillStyle = 'rgba(' + i + ',' + (Math.floor(i*1.5) % 256) + ',' + (Math.floor(i*23.3) % 256) + ',' + (i/256) + ')';
+ ctx.fillRect(x, y, 1, 1);
+ }
+ }
+ var imgdata1 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ var olddata = [];
+ for (var i = 0; i < imgdata1.data.length; ++i)
+ olddata[i] = imgdata1.data[i];
+
+ ctx.putImageData(imgdata1, 0.1, 0.2);
+
+ var imgdata2 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ for (var i = 0; i < imgdata2.data.length; ++i) {
+ _assertSame(olddata[i], imgdata2.data[i], "olddata[\""+(i)+"\"]", "imgdata2.data[\""+(i)+"\"]");
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.html b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.html
new file mode 100644
index 0000000000..1488e7b111
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.imageData.put.wrongtype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.imageData.put.wrongtype</h1>
+<p class="desc">putImageData() does not accept non-ImageData objects</p>
+
+
+<script>
+var t = async_test("putImageData() does not accept non-ImageData objects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = { width: 1, height: 1, data: [255, 0, 0, 255] };
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.putImageData("cheese", 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(42, 0, 0); });
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.worker.js b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.worker.js
new file mode 100644
index 0000000000..bf4d6dfedf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/pixel-manipulation/2d.imageData.put.wrongtype.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.imageData.put.wrongtype
+// Description:putImageData() does not accept non-ImageData objects
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("putImageData() does not accept non-ImageData objects");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var imgdata = { width: 1, height: 1, data: [255, 0, 0, 255] };
+ assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.putImageData("cheese", 0, 0); });
+ assert_throws_js(TypeError, function() { ctx.putImageData(42, 0, 0); });
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.html
new file mode 100644
index 0000000000..7396ca120a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.basic</h1>
+<p class="desc">reset clears to transparent black</p>
+
+
+<script>
+var t = async_test("reset clears to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.reset();
+ _assertPixel(canvas, 0,0, 0,0,0,0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ _assertPixel(canvas, 25,50, 0,0,0,0);
+ _assertPixel(canvas, 100,50, 0,0,0,0);
+ _assertPixel(canvas, 0,50, 0,0,0,0);
+ _assertPixel(canvas, 100,0, 0,0,0,0);
+ t.done();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.worker.js
new file mode 100644
index 0000000000..180bffbfac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.basic.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.basic
+// Description:reset clears to transparent black
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("reset clears to transparent black");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.reset();
+ _assertPixel(canvas, 0,0, 0,0,0,0);
+ _assertPixel(canvas, 50,25, 0,0,0,0);
+ _assertPixel(canvas, 25,50, 0,0,0,0);
+ _assertPixel(canvas, 100,50, 0,0,0,0);
+ _assertPixel(canvas, 0,50, 0,0,0,0);
+ _assertPixel(canvas, 100,0, 0,0,0,0);
+ t.done();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow-expected.html
new file mode 100644
index 0000000000..182f7e40cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.drop_shadow</title>
+<h1>2d.reset.render.drop_shadow</h1>
+<p class="desc">check that drop shadows are correctly rendered after reset</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(100, 100, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.html
new file mode 100644
index 0000000000..e6decd1687
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.drop_shadow-expected.html">
+<title>Canvas test: 2d.reset.render.drop_shadow</title>
+<h1>2d.reset.render.drop_shadow</h1>
+<p class="desc">check that drop shadows are correctly rendered after reset</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(500, 500);
+ const ctx = canvas.getContext('2d');
+
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = "red";
+ ctx.shadowBlur = 10;
+
+ ctx.reset();
+
+ ctx.fillRect(100, 100, 100, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.w.html
new file mode 100644
index 0000000000..0ceba2f91d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.drop_shadow.w.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.reset.render.drop_shadow-expected.html">
+<title>Canvas test: 2d.reset.render.drop_shadow</title>
+<h1>2d.reset.render.drop_shadow</h1>
+<p class="desc">check that drop shadows are correctly rendered after reset</p>
+<canvas id="canvas" width="500" height="500">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(500, 500);
+ const ctx = canvas.getContext('2d');
+
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = "red";
+ ctx.shadowBlur = 10;
+
+ ctx.reset();
+
+ ctx.fillRect(100, 100, 100, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation-expected.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation-expected.html
new file mode 100644
index 0000000000..1f9d247634
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.global_composite_operation</title>
+<h1>2d.reset.render.global_composite_operation</h1>
+<p class="desc">check that canvas correctly renders rectangles with the default global composite operation after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(10, 10, 100, 100);
+ ctx.fillRect(50, 50, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.html
new file mode 100644
index 0000000000..4ddcc8d8f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.global_composite_operation-expected.html">
+<title>Canvas test: 2d.reset.render.global_composite_operation</title>
+<h1>2d.reset.render.global_composite_operation</h1>
+<p class="desc">check that canvas correctly renders rectangles with the default global composite operation after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = "xor";
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 100, 100);
+ ctx.fillRect(50, 50, 100, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.w.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.w.html
new file mode 100644
index 0000000000..6df07a47e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.global_composite_operation.w.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.reset.render.global_composite_operation-expected.html">
+<title>Canvas test: 2d.reset.render.global_composite_operation</title>
+<h1>2d.reset.render.global_composite_operation</h1>
+<p class="desc">check that canvas correctly renders rectangles with the default global composite operation after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = "xor";
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 100, 100);
+ ctx.fillRect(50, 50, 100, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line-expected.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line-expected.html
new file mode 100644
index 0000000000..dcd648d8c3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line-expected.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.line</title>
+<h1>2d.reset.render.line</h1>
+<p class="desc">check that lines are correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.moveTo(100, 100);
+ ctx.lineTo(100, 300);
+ ctx.lineTo(300, 300);
+ ctx.lineTo(300, 100);
+ ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.html
new file mode 100644
index 0000000000..0e478cbf9d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.line-expected.html">
+<title>Canvas test: 2d.reset.render.line</title>
+<h1>2d.reset.render.line</h1>
+<p class="desc">check that lines are correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 10;
+ ctx.lineCap = "round";
+ ctx.lineJoin = "bevel";
+ ctx.lineDashOffset = 10;
+ ctx.setLineDash([20]);
+
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(100, 100);
+ ctx.lineTo(100, 300);
+ ctx.lineTo(300, 300);
+ ctx.lineTo(300, 100);
+ ctx.stroke();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.w.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.w.html
new file mode 100644
index 0000000000..e85f155b32
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.line.w.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.reset.render.line-expected.html">
+<title>Canvas test: 2d.reset.render.line</title>
+<h1>2d.reset.render.line</h1>
+<p class="desc">check that lines are correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 10;
+ ctx.lineCap = "round";
+ ctx.lineJoin = "bevel";
+ ctx.lineDashOffset = 10;
+ ctx.setLineDash([20]);
+
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(100, 100);
+ ctx.lineTo(100, 300);
+ ctx.lineTo(300, 300);
+ ctx.lineTo(300, 100);
+ ctx.stroke();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc-expected.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc-expected.html
new file mode 100644
index 0000000000..c359e6b42e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.misc</title>
+<h1>2d.reset.render.misc</h1>
+<p class="desc">check that canvas correctly renders rectangles after reset (states not covered by other tests)</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(0, 0, 100, 100);
+ ctx.strokeRect(150, 150, 100, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.html
new file mode 100644
index 0000000000..b471327d98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.misc-expected.html">
+<title>Canvas test: 2d.reset.render.misc</title>
+<h1>2d.reset.render.misc</h1>
+<p class="desc">check that canvas correctly renders rectangles after reset (states not covered by other tests)</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = "red";
+ ctx.strokeStyle = "red";
+ ctx.globalAlpha = 0.5;
+ ctx.filter = "blur(2px)";
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 100, 100);
+ ctx.strokeRect(150, 150, 100, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.w.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.w.html
new file mode 100644
index 0000000000..eef646df66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.misc.w.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.reset.render.misc-expected.html">
+<title>Canvas test: 2d.reset.render.misc</title>
+<h1>2d.reset.render.misc</h1>
+<p class="desc">check that canvas correctly renders rectangles after reset (states not covered by other tests)</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = "red";
+ ctx.strokeStyle = "red";
+ ctx.globalAlpha = 0.5;
+ ctx.filter = "blur(2px)";
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 100, 100);
+ ctx.strokeRect(150, 150, 100, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit-expected.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit-expected.html
new file mode 100644
index 0000000000..c91f485c53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit-expected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.miter_limit</title>
+<h1>2d.reset.render.miter_limit</h1>
+<p class="desc">check that the lines are correctly rendered with the default miter limit after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 10;
+
+ ctx.beginPath();
+ ctx.moveTo(0, 100);
+ for (let i = 0; i < 24; i++) {
+ const dy = i % 2 === 0 ? 25 : -25;
+ ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
+ }
+ ctx.stroke();
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.html
new file mode 100644
index 0000000000..c00284bbc2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.miter_limit-expected.html">
+<title>Canvas test: 2d.reset.render.miter_limit</title>
+<h1>2d.reset.render.miter_limit</h1>
+<p class="desc">check that the lines are correctly rendered with the default miter limit after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.miterLimit = 6;
+
+ ctx.reset();
+
+ ctx.lineWidth = 10;
+
+ ctx.beginPath();
+ ctx.moveTo(0, 100);
+ for (let i = 0; i < 24; i++) {
+ const dy = i % 2 === 0 ? 25 : -25;
+ ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
+ }
+ ctx.stroke();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.w.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.w.html
new file mode 100644
index 0000000000..1f98606b55
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.miter_limit.w.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.reset.render.miter_limit-expected.html">
+<title>Canvas test: 2d.reset.render.miter_limit</title>
+<h1>2d.reset.render.miter_limit</h1>
+<p class="desc">check that the lines are correctly rendered with the default miter limit after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.miterLimit = 6;
+
+ ctx.reset();
+
+ ctx.lineWidth = 10;
+
+ ctx.beginPath();
+ ctx.moveTo(0, 100);
+ for (let i = 0; i < 24; i++) {
+ const dy = i % 2 === 0 ? 25 : -25;
+ ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
+ }
+ ctx.stroke();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text-expected.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text-expected.html
new file mode 100644
index 0000000000..7221483b02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.render.text</title>
+<h1>2d.reset.render.text</h1>
+<p class="desc">check that text is correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillText("Lorem ipsum dolor sit amet, consectetur adipiscing elit", 0, 10);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.html
new file mode 100644
index 0000000000..31e35db71c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.render.text-expected.html">
+<title>Canvas test: 2d.reset.render.text</title>
+<h1>2d.reset.render.text</h1>
+<p class="desc">check that text is correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "24px serif";
+ ctx.textAlign = "center";
+ ctx.textBaseline = "hanging";
+ ctx.direction = "rtl";
+ ctx.letterSpacing = "10px";
+ ctx.fontKerning = "none";
+ ctx.fontStretch = "semi-condensed";
+ ctx.fontVariantCaps = "tilting-caps";
+ ctx.textRendering = "optimizeLegibility";
+ ctx.wordSpacing = "20px";
+
+ ctx.reset();
+
+ ctx.fillText("Lorem ipsum dolor sit amet, consectetur adipiscing elit", 0, 10);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.w.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.w.html
new file mode 100644
index 0000000000..6ddfd9fd9d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.render.text.w.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.reset.render.text-expected.html">
+<title>Canvas test: 2d.reset.render.text</title>
+<h1>2d.reset.render.text</h1>
+<p class="desc">check that text is correctly rendered after reset</p>
+<canvas id="canvas" width="400" height="400">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(400, 400);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "24px serif";
+ ctx.textAlign = "center";
+ ctx.textBaseline = "hanging";
+ ctx.direction = "rtl";
+ ctx.letterSpacing = "10px";
+ ctx.fontKerning = "none";
+ ctx.fontStretch = "semi-condensed";
+ ctx.fontVariantCaps = "tilting-caps";
+ ctx.textRendering = "optimizeLegibility";
+ ctx.wordSpacing = "20px";
+
+ ctx.reset();
+
+ ctx.fillText("Lorem ipsum dolor sit amet, consectetur adipiscing elit", 0, 10);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip-expected.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip-expected.html
new file mode 100644
index 0000000000..974b37fab4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.reset.state.clip</title>
+<h1>2d.reset.state.clip</h1>
+<p class="desc">check that the clip is reset</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillRect(0, 0, 200, 200);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.html
new file mode 100644
index 0000000000..2f53da7a49
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.reset.state.clip-expected.html">
+<title>Canvas test: 2d.reset.state.clip</title>
+<h1>2d.reset.state.clip</h1>
+<p class="desc">check that the clip is reset</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.clip();
+
+ ctx.fillRect(0, 0, 200, 200);
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 200, 200);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.w.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.w.html
new file mode 100644
index 0000000000..ec4bdf5b23
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.clip.w.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.reset.state.clip-expected.html">
+<title>Canvas test: 2d.reset.state.clip</title>
+<h1>2d.reset.state.clip</h1>
+<p class="desc">check that the clip is reset</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.clip();
+
+ ctx.fillRect(0, 0, 200, 200);
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 200, 200);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.html
new file mode 100644
index 0000000000..f2dc299e97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.direction</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.direction</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.direction;
+
+ ctx.direction = 'rtl';
+ _assert(ctx.direction == 'rtl', "ctx.direction == 'rtl'");
+
+ ctx.reset();
+ _assert(ctx.direction == default_value, "ctx.direction == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.worker.js
new file mode 100644
index 0000000000..3d6b835050
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.direction.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.direction
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.direction;
+
+ ctx.direction = 'rtl';
+ _assert(ctx.direction == 'rtl', "ctx.direction == 'rtl'");
+
+ ctx.reset();
+ _assert(ctx.direction == default_value, "ctx.direction == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.html
new file mode 100644
index 0000000000..1fdd2b773a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.fill_style</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.fill_style</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fillStyle;
+
+ ctx.fillStyle = '#ffffff';
+ _assert(ctx.fillStyle == '#ffffff', "ctx.fillStyle == '#ffffff'");
+
+ ctx.reset();
+ _assert(ctx.fillStyle == default_value, "ctx.fillStyle == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.worker.js
new file mode 100644
index 0000000000..c574824b0a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.fill_style.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.fill_style
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fillStyle;
+
+ ctx.fillStyle = '#ffffff';
+ _assert(ctx.fillStyle == '#ffffff', "ctx.fillStyle == '#ffffff'");
+
+ ctx.reset();
+ _assert(ctx.fillStyle == default_value, "ctx.fillStyle == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.html
new file mode 100644
index 0000000000..af898c7dd1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.filter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.filter</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.filter;
+
+ ctx.filter = 'blur(10px)';
+ _assert(ctx.filter == 'blur(10px)', "ctx.filter == 'blur(10px)'");
+
+ ctx.reset();
+ _assert(ctx.filter == default_value, "ctx.filter == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.worker.js
new file mode 100644
index 0000000000..f781a9fa34
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.filter.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.filter
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.filter;
+
+ ctx.filter = 'blur(10px)';
+ _assert(ctx.filter == 'blur(10px)', "ctx.filter == 'blur(10px)'");
+
+ ctx.reset();
+ _assert(ctx.filter == default_value, "ctx.filter == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.html
new file mode 100644
index 0000000000..69bbf3261e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.font</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.font</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.font;
+
+ ctx.font = '16px sans-serif';
+ _assert(ctx.font == '16px sans-serif', "ctx.font == '16px sans-serif'");
+
+ ctx.reset();
+ _assert(ctx.font == default_value, "ctx.font == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.worker.js
new file mode 100644
index 0000000000..ea6f4cc184
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.font
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.font;
+
+ ctx.font = '16px sans-serif';
+ _assert(ctx.font == '16px sans-serif', "ctx.font == '16px sans-serif'");
+
+ ctx.reset();
+ _assert(ctx.font == default_value, "ctx.font == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.html
new file mode 100644
index 0000000000..27954486c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.font_kerning</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.font_kerning</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fontKerning;
+
+ ctx.fontKerning = 'normal';
+ _assert(ctx.fontKerning == 'normal', "ctx.fontKerning == 'normal'");
+
+ ctx.reset();
+ _assert(ctx.fontKerning == default_value, "ctx.fontKerning == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.worker.js
new file mode 100644
index 0000000000..1c21249b9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_kerning.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.font_kerning
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fontKerning;
+
+ ctx.fontKerning = 'normal';
+ _assert(ctx.fontKerning == 'normal', "ctx.fontKerning == 'normal'");
+
+ ctx.reset();
+ _assert(ctx.fontKerning == default_value, "ctx.fontKerning == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.html
new file mode 100644
index 0000000000..b1e2217320
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.font_stretch</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.font_stretch</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fontStretch;
+
+ ctx.fontStretch = 'ultra-condensed';
+ _assert(ctx.fontStretch == 'ultra-condensed', "ctx.fontStretch == 'ultra-condensed'");
+
+ ctx.reset();
+ _assert(ctx.fontStretch == default_value, "ctx.fontStretch == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.worker.js
new file mode 100644
index 0000000000..71bb6aff48
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_stretch.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.font_stretch
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fontStretch;
+
+ ctx.fontStretch = 'ultra-condensed';
+ _assert(ctx.fontStretch == 'ultra-condensed', "ctx.fontStretch == 'ultra-condensed'");
+
+ ctx.reset();
+ _assert(ctx.fontStretch == default_value, "ctx.fontStretch == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.html
new file mode 100644
index 0000000000..7d0518c021
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.font_variant_caps</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.font_variant_caps</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fontVariantCaps;
+
+ ctx.fontVariantCaps = 'unicase';
+ _assert(ctx.fontVariantCaps == 'unicase', "ctx.fontVariantCaps == 'unicase'");
+
+ ctx.reset();
+ _assert(ctx.fontVariantCaps == default_value, "ctx.fontVariantCaps == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.worker.js
new file mode 100644
index 0000000000..e89a8bda42
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.font_variant_caps.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.font_variant_caps
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.fontVariantCaps;
+
+ ctx.fontVariantCaps = 'unicase';
+ _assert(ctx.fontVariantCaps == 'unicase', "ctx.fontVariantCaps == 'unicase'");
+
+ ctx.reset();
+ _assert(ctx.fontVariantCaps == default_value, "ctx.fontVariantCaps == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.html
new file mode 100644
index 0000000000..fe87aedf84
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.global_alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.global_alpha</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.globalAlpha;
+
+ ctx.globalAlpha = 0.5;
+ _assert(ctx.globalAlpha == 0.5, "ctx.globalAlpha == 0.5");
+
+ ctx.reset();
+ _assert(ctx.globalAlpha == default_value, "ctx.globalAlpha == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.worker.js
new file mode 100644
index 0000000000..518a8cbb46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_alpha.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.global_alpha
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.globalAlpha;
+
+ ctx.globalAlpha = 0.5;
+ _assert(ctx.globalAlpha == 0.5, "ctx.globalAlpha == 0.5");
+
+ ctx.reset();
+ _assert(ctx.globalAlpha == default_value, "ctx.globalAlpha == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.html
new file mode 100644
index 0000000000..647349c94a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.global_composite_operation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.global_composite_operation</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.globalCompositeOperation;
+
+ ctx.globalCompositeOperation = 'destination-over';
+ _assert(ctx.globalCompositeOperation == 'destination-over', "ctx.globalCompositeOperation == 'destination-over'");
+
+ ctx.reset();
+ _assert(ctx.globalCompositeOperation == default_value, "ctx.globalCompositeOperation == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.worker.js
new file mode 100644
index 0000000000..c94f15b232
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.global_composite_operation.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.global_composite_operation
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.globalCompositeOperation;
+
+ ctx.globalCompositeOperation = 'destination-over';
+ _assert(ctx.globalCompositeOperation == 'destination-over', "ctx.globalCompositeOperation == 'destination-over'");
+
+ ctx.reset();
+ _assert(ctx.globalCompositeOperation == default_value, "ctx.globalCompositeOperation == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.html
new file mode 100644
index 0000000000..c0b7f29aca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.image_smoothing_enabled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.image_smoothing_enabled</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.imageSmoothingEnabled;
+
+ ctx.imageSmoothingEnabled = false;
+ _assert(ctx.imageSmoothingEnabled == false, "ctx.imageSmoothingEnabled == false");
+
+ ctx.reset();
+ _assert(ctx.imageSmoothingEnabled == default_value, "ctx.imageSmoothingEnabled == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.worker.js
new file mode 100644
index 0000000000..7010fb899c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_enabled.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.image_smoothing_enabled
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.imageSmoothingEnabled;
+
+ ctx.imageSmoothingEnabled = false;
+ _assert(ctx.imageSmoothingEnabled == false, "ctx.imageSmoothingEnabled == false");
+
+ ctx.reset();
+ _assert(ctx.imageSmoothingEnabled == default_value, "ctx.imageSmoothingEnabled == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.html
new file mode 100644
index 0000000000..12a6367ff9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.image_smoothing_quality</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.image_smoothing_quality</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.imageSmoothingQuality;
+
+ ctx.imageSmoothingQuality = 'high';
+ _assert(ctx.imageSmoothingQuality == 'high', "ctx.imageSmoothingQuality == 'high'");
+
+ ctx.reset();
+ _assert(ctx.imageSmoothingQuality == default_value, "ctx.imageSmoothingQuality == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.worker.js
new file mode 100644
index 0000000000..7429666691
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.image_smoothing_quality.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.image_smoothing_quality
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.imageSmoothingQuality;
+
+ ctx.imageSmoothingQuality = 'high';
+ _assert(ctx.imageSmoothingQuality == 'high', "ctx.imageSmoothingQuality == 'high'");
+
+ ctx.reset();
+ _assert(ctx.imageSmoothingQuality == default_value, "ctx.imageSmoothingQuality == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.html
new file mode 100644
index 0000000000..addb0c62ad
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.letter_spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.letter_spacing</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.letterSpacing;
+
+ ctx.letterSpacing = '12px';
+ _assert(ctx.letterSpacing == '12px', "ctx.letterSpacing == '12px'");
+
+ ctx.reset();
+ _assert(ctx.letterSpacing == default_value, "ctx.letterSpacing == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.worker.js
new file mode 100644
index 0000000000..e0dfae0a8e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.letter_spacing.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.letter_spacing
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.letterSpacing;
+
+ ctx.letterSpacing = '12px';
+ _assert(ctx.letterSpacing == '12px', "ctx.letterSpacing == '12px'");
+
+ ctx.reset();
+ _assert(ctx.letterSpacing == default_value, "ctx.letterSpacing == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.html
new file mode 100644
index 0000000000..9b528b3448
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.line_cap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.line_cap</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineCap;
+
+ ctx.lineCap = 'square';
+ _assert(ctx.lineCap == 'square', "ctx.lineCap == 'square'");
+
+ ctx.reset();
+ _assert(ctx.lineCap == default_value, "ctx.lineCap == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.worker.js
new file mode 100644
index 0000000000..c3a94f2cbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_cap.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.line_cap
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineCap;
+
+ ctx.lineCap = 'square';
+ _assert(ctx.lineCap == 'square', "ctx.lineCap == 'square'");
+
+ ctx.reset();
+ _assert(ctx.lineCap == default_value, "ctx.lineCap == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.html
new file mode 100644
index 0000000000..fd4edf58cf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.line_dash</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.line_dash</h1>
+<p class="desc">check that the line dash is reset</p>
+
+
+<script>
+var t = async_test("check that the line dash is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.setLineDash([1, 2]);
+
+ ctx.reset();
+ _assert(ctx.getLineDash().length == 0, "ctx.getLineDash().length == 0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.worker.js
new file mode 100644
index 0000000000..841475d876
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.line_dash
+// Description:check that the line dash is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the line dash is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.setLineDash([1, 2]);
+
+ ctx.reset();
+ _assert(ctx.getLineDash().length == 0, "ctx.getLineDash().length == 0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.html
new file mode 100644
index 0000000000..475db49f82
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.line_dash_offset</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.line_dash_offset</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineDashOffset;
+
+ ctx.lineDashOffset = 1.0;
+ _assert(ctx.lineDashOffset == 1.0, "ctx.lineDashOffset == 1.0");
+
+ ctx.reset();
+ _assert(ctx.lineDashOffset == default_value, "ctx.lineDashOffset == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.worker.js
new file mode 100644
index 0000000000..5e0d8dd47c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_dash_offset.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.line_dash_offset
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineDashOffset;
+
+ ctx.lineDashOffset = 1.0;
+ _assert(ctx.lineDashOffset == 1.0, "ctx.lineDashOffset == 1.0");
+
+ ctx.reset();
+ _assert(ctx.lineDashOffset == default_value, "ctx.lineDashOffset == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.html
new file mode 100644
index 0000000000..793c1d9bc4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.line_join</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.line_join</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineJoin;
+
+ ctx.lineJoin = 'bevel';
+ _assert(ctx.lineJoin == 'bevel', "ctx.lineJoin == 'bevel'");
+
+ ctx.reset();
+ _assert(ctx.lineJoin == default_value, "ctx.lineJoin == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.worker.js
new file mode 100644
index 0000000000..9d5e76757b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_join.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.line_join
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineJoin;
+
+ ctx.lineJoin = 'bevel';
+ _assert(ctx.lineJoin == 'bevel', "ctx.lineJoin == 'bevel'");
+
+ ctx.reset();
+ _assert(ctx.lineJoin == default_value, "ctx.lineJoin == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.html
new file mode 100644
index 0000000000..8cdf45f700
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.line_width</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.line_width</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineWidth;
+
+ ctx.lineWidth = 1;
+ _assert(ctx.lineWidth == 1, "ctx.lineWidth == 1");
+
+ ctx.reset();
+ _assert(ctx.lineWidth == default_value, "ctx.lineWidth == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.worker.js
new file mode 100644
index 0000000000..1e28f93d66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.line_width.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.line_width
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.lineWidth;
+
+ ctx.lineWidth = 1;
+ _assert(ctx.lineWidth == 1, "ctx.lineWidth == 1");
+
+ ctx.reset();
+ _assert(ctx.lineWidth == default_value, "ctx.lineWidth == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.html
new file mode 100644
index 0000000000..7f47f9a6be
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.miter_limit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.miter_limit</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.miterLimit;
+
+ ctx.miterLimit = 1.0;
+ _assert(ctx.miterLimit == 1.0, "ctx.miterLimit == 1.0");
+
+ ctx.reset();
+ _assert(ctx.miterLimit == default_value, "ctx.miterLimit == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.worker.js
new file mode 100644
index 0000000000..3945a662d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.miter_limit.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.miter_limit
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.miterLimit;
+
+ ctx.miterLimit = 1.0;
+ _assert(ctx.miterLimit == 1.0, "ctx.miterLimit == 1.0");
+
+ ctx.reset();
+ _assert(ctx.miterLimit == default_value, "ctx.miterLimit == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.html
new file mode 100644
index 0000000000..e7075ce102
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.shadow_blur</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.shadow_blur</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowBlur;
+
+ ctx.shadowBlur = 10.0;
+ _assert(ctx.shadowBlur == 10.0, "ctx.shadowBlur == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowBlur == default_value, "ctx.shadowBlur == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.worker.js
new file mode 100644
index 0000000000..d82933169d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_blur.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.shadow_blur
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowBlur;
+
+ ctx.shadowBlur = 10.0;
+ _assert(ctx.shadowBlur == 10.0, "ctx.shadowBlur == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowBlur == default_value, "ctx.shadowBlur == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.html
new file mode 100644
index 0000000000..ad928acf46
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.shadow_color</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.shadow_color</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowColor;
+
+ ctx.shadowColor = '#ff0000';
+ _assert(ctx.shadowColor == '#ff0000', "ctx.shadowColor == '#ff0000'");
+
+ ctx.reset();
+ _assert(ctx.shadowColor == default_value, "ctx.shadowColor == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.worker.js
new file mode 100644
index 0000000000..6ad1e83be2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_color.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.shadow_color
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowColor;
+
+ ctx.shadowColor = '#ff0000';
+ _assert(ctx.shadowColor == '#ff0000', "ctx.shadowColor == '#ff0000'");
+
+ ctx.reset();
+ _assert(ctx.shadowColor == default_value, "ctx.shadowColor == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.html
new file mode 100644
index 0000000000..e3742e4dbc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.shadow_offset_x</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.shadow_offset_x</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowOffsetX;
+
+ ctx.shadowOffsetX = 10.0;
+ _assert(ctx.shadowOffsetX == 10.0, "ctx.shadowOffsetX == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowOffsetX == default_value, "ctx.shadowOffsetX == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.worker.js
new file mode 100644
index 0000000000..4247820a4d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_x.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.shadow_offset_x
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowOffsetX;
+
+ ctx.shadowOffsetX = 10.0;
+ _assert(ctx.shadowOffsetX == 10.0, "ctx.shadowOffsetX == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowOffsetX == default_value, "ctx.shadowOffsetX == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.html
new file mode 100644
index 0000000000..64901ef492
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.shadow_offset_y</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.shadow_offset_y</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowOffsetY;
+
+ ctx.shadowOffsetY = 10.0;
+ _assert(ctx.shadowOffsetY == 10.0, "ctx.shadowOffsetY == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowOffsetY == default_value, "ctx.shadowOffsetY == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.worker.js
new file mode 100644
index 0000000000..0c1926ebca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.shadow_offset_y.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.shadow_offset_y
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.shadowOffsetY;
+
+ ctx.shadowOffsetY = 10.0;
+ _assert(ctx.shadowOffsetY == 10.0, "ctx.shadowOffsetY == 10.0");
+
+ ctx.reset();
+ _assert(ctx.shadowOffsetY == default_value, "ctx.shadowOffsetY == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.html
new file mode 100644
index 0000000000..79803b2828
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.stroke_style</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.stroke_style</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.strokeStyle;
+
+ ctx.strokeStyle = '#ffffff';
+ _assert(ctx.strokeStyle == '#ffffff', "ctx.strokeStyle == '#ffffff'");
+
+ ctx.reset();
+ _assert(ctx.strokeStyle == default_value, "ctx.strokeStyle == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.worker.js
new file mode 100644
index 0000000000..99e1eaaed5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.stroke_style.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.stroke_style
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.strokeStyle;
+
+ ctx.strokeStyle = '#ffffff';
+ _assert(ctx.strokeStyle == '#ffffff', "ctx.strokeStyle == '#ffffff'");
+
+ ctx.reset();
+ _assert(ctx.strokeStyle == default_value, "ctx.strokeStyle == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.html
new file mode 100644
index 0000000000..c1a33d6f3d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.text_align</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.text_align</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.textAlign;
+
+ ctx.textAlign = 'end';
+ _assert(ctx.textAlign == 'end', "ctx.textAlign == 'end'");
+
+ ctx.reset();
+ _assert(ctx.textAlign == default_value, "ctx.textAlign == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.worker.js
new file mode 100644
index 0000000000..087d3195e4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_align.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.text_align
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.textAlign;
+
+ ctx.textAlign = 'end';
+ _assert(ctx.textAlign == 'end', "ctx.textAlign == 'end'");
+
+ ctx.reset();
+ _assert(ctx.textAlign == default_value, "ctx.textAlign == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.html
new file mode 100644
index 0000000000..acb56e4a00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.text_baseline</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.text_baseline</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.textBaseline;
+
+ ctx.textBaseline = 'middle';
+ _assert(ctx.textBaseline == 'middle', "ctx.textBaseline == 'middle'");
+
+ ctx.reset();
+ _assert(ctx.textBaseline == default_value, "ctx.textBaseline == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.worker.js
new file mode 100644
index 0000000000..9a171326cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_baseline.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.text_baseline
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.textBaseline;
+
+ ctx.textBaseline = 'middle';
+ _assert(ctx.textBaseline == 'middle', "ctx.textBaseline == 'middle'");
+
+ ctx.reset();
+ _assert(ctx.textBaseline == default_value, "ctx.textBaseline == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.html
new file mode 100644
index 0000000000..174dbb3801
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.text_rendering</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.text_rendering</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.textRendering;
+
+ ctx.textRendering = 'geometricPrecision';
+ _assert(ctx.textRendering == 'geometricPrecision', "ctx.textRendering == 'geometricPrecision'");
+
+ ctx.reset();
+ _assert(ctx.textRendering == default_value, "ctx.textRendering == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.worker.js
new file mode 100644
index 0000000000..df4cea1044
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.text_rendering.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.text_rendering
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.textRendering;
+
+ ctx.textRendering = 'geometricPrecision';
+ _assert(ctx.textRendering == 'geometricPrecision', "ctx.textRendering == 'geometricPrecision'");
+
+ ctx.reset();
+ _assert(ctx.textRendering == default_value, "ctx.textRendering == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.html
new file mode 100644
index 0000000000..c30e459b30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.transformation_matrix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.transformation_matrix</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(2, 2);
+
+ ctx.reset();
+ _assert(ctx.getTransform().isIdentity, "ctx.getTransform().isIdentity");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.worker.js
new file mode 100644
index 0000000000..2ae105c20e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.transformation_matrix.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.transformation_matrix
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.scale(2, 2);
+
+ ctx.reset();
+ _assert(ctx.getTransform().isIdentity, "ctx.getTransform().isIdentity");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.html b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.html
new file mode 100644
index 0000000000..470db2cf98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.reset.state.word_spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.reset.state.word_spacing</h1>
+<p class="desc">check that the state is reset</p>
+
+
+<script>
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.wordSpacing;
+
+ ctx.wordSpacing = '12px';
+ _assert(ctx.wordSpacing == '12px', "ctx.wordSpacing == '12px'");
+
+ ctx.reset();
+ _assert(ctx.wordSpacing == default_value, "ctx.wordSpacing == default_value");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.worker.js
new file mode 100644
index 0000000000..9e8c717f78
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/reset/2d.reset.state.word_spacing.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.reset.state.word_spacing
+// Description:check that the state is reset
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("check that the state is reset");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ const default_value = ctx.wordSpacing;
+
+ ctx.wordSpacing = '12px';
+ _assert(ctx.wordSpacing == '12px', "ctx.wordSpacing == '12px'");
+
+ ctx.reset();
+ _assert(ctx.wordSpacing == default_value, "ctx.wordSpacing == default_value");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/set-proprietary-font-names-001-crash.html b/testing/web-platform/tests/html/canvas/offscreen/set-proprietary-font-names-001-crash.html
new file mode 100644
index 0000000000..dfa661655e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/set-proprietary-font-names-001-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE>
+<title>Setting font of offscreen</title>
+<script src="/css/css-fonts/support/font-family-keywords.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-family-prop">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1056386">
+<script>
+ let ctx = (new OffscreenCanvas(1024, 50)).getContext('2d');
+ function setFont(keyword) { ctx.font = `12px ${keyword}` };
+ kNonGenericFontFamilyKeywords.forEach(setFont);
+ kGenericFontFamilyKeywords.forEach(keyword => {
+ setFont(`-webkit-${keyword}`);
+ });
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.html
new file mode 100644
index 0000000000..765cf41b21
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.alpha.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.alpha.1</h1>
+<p class="desc">Shadow color alpha components are used</p>
+
+
+<script>
+var t = async_test("Shadow color alpha components are used");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(255, 0, 0, 0.01)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 4);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.worker.js
new file mode 100644
index 0000000000..869aa017e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.1.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.alpha.1
+// Description:Shadow color alpha components are used
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadow color alpha components are used");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(255, 0, 0, 0.01)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 4);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.html
new file mode 100644
index 0000000000..be2209608f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.alpha.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.alpha.2</h1>
+<p class="desc">Shadow color alpha components are used</p>
+
+
+<script>
+var t = async_test("Shadow color alpha components are used");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.5)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.worker.js
new file mode 100644
index 0000000000..dce91f2e4d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.2.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.alpha.2
+// Description:Shadow color alpha components are used
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadow color alpha components are used");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.5)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.html
new file mode 100644
index 0000000000..7239b3cea7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.alpha.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.alpha.3</h1>
+<p class="desc">Shadows are affected by globalAlpha</p>
+
+
+<script>
+var t = async_test("Shadows are affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.5;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.worker.js
new file mode 100644
index 0000000000..93fc665ced
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.3.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.alpha.3
+// Description:Shadows are affected by globalAlpha
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.5;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.html
new file mode 100644
index 0000000000..468db2a716
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.alpha.4</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.alpha.4</h1>
+<p class="desc">Shadows with alpha components are correctly affected by globalAlpha</p>
+
+
+<script>
+var t = async_test("Shadows with alpha components are correctly affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.707)';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.707;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.worker.js
new file mode 100644
index 0000000000..2be63d3eff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.4.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.alpha.4
+// Description:Shadows with alpha components are correctly affected by globalAlpha
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows with alpha components are correctly affected by globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.707)';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.707;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.html
new file mode 100644
index 0000000000..92ac9717f2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.alpha.5</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.alpha.5</h1>
+<p class="desc">Shadows of shapes with alpha components are drawn correctly</p>
+
+
+<script>
+var t = async_test("Shadows of shapes with alpha components are drawn correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgba(64, 0, 0, 0.5)';
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.worker.js
new file mode 100644
index 0000000000..016616ac8c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.alpha.5.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.alpha.5
+// Description:Shadows of shapes with alpha components are drawn correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows of shapes with alpha components are drawn correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgba(64, 0, 0, 0.5)';
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.html
new file mode 100644
index 0000000000..21225883df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowBlur.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowBlur.initial</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.worker.js
new file mode 100644
index 0000000000..7643f0edfa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.initial.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowBlur.initial
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.html
new file mode 100644
index 0000000000..51d1a4a804
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowBlur.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowBlur.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -2;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = Infinity;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -Infinity;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = NaN;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = 'string';
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = true;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = false;
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.worker.js
new file mode 100644
index 0000000000..2e3a28b789
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.invalid.worker.js
@@ -0,0 +1,48 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowBlur.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -2;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = Infinity;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -Infinity;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = NaN;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = 'string';
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = true;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = false;
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.html
new file mode 100644
index 0000000000..06495f6c31
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowBlur.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowBlur.valid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowBlur = 1;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 0.5;
+ _assertSame(ctx.shadowBlur, 0.5, "ctx.shadowBlur", "0.5");
+
+ ctx.shadowBlur = 1e6;
+ _assertSame(ctx.shadowBlur, 1e6, "ctx.shadowBlur", "1e6");
+
+ ctx.shadowBlur = 0;
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.worker.js
new file mode 100644
index 0000000000..d0292edaec
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowBlur.valid.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowBlur.valid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowBlur = 1;
+ _assertSame(ctx.shadowBlur, 1, "ctx.shadowBlur", "1");
+
+ ctx.shadowBlur = 0.5;
+ _assertSame(ctx.shadowBlur, 0.5, "ctx.shadowBlur", "0.5");
+
+ ctx.shadowBlur = 1e6;
+ _assertSame(ctx.shadowBlur, 1e6, "ctx.shadowBlur", "1e6");
+
+ ctx.shadowBlur = 0;
+ _assertSame(ctx.shadowBlur, 0, "ctx.shadowBlur", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.html
new file mode 100644
index 0000000000..92a8bd1500
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowColor.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowColor.initial</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.shadowColor, 'rgba(0, 0, 0, 0)', "ctx.shadowColor", "'rgba(0, 0, 0, 0)'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.worker.js
new file mode 100644
index 0000000000..8b1ec38d7f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.initial.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowColor.initial
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.shadowColor, 'rgba(0, 0, 0, 0)', "ctx.shadowColor", "'rgba(0, 0, 0, 0)'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.html
new file mode 100644
index 0000000000..ac1d9e7333
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowColor.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowColor.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'bogus';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'red bogus';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = ctx;
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = undefined;
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.worker.js
new file mode 100644
index 0000000000..c962f2508d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.invalid.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowColor.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'bogus';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'red bogus';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = ctx;
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = undefined;
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.html
new file mode 100644
index 0000000000..340f11f54f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowColor.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowColor.valid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowColor = 'lime';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = 'RGBA(0,255, 0,0)';
+ _assertSame(ctx.shadowColor, 'rgba(0, 255, 0, 0)', "ctx.shadowColor", "'rgba(0, 255, 0, 0)'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.worker.js
new file mode 100644
index 0000000000..6d7eb0504d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowColor.valid.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowColor.valid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowColor = 'lime';
+ _assertSame(ctx.shadowColor, '#00ff00', "ctx.shadowColor", "'#00ff00'");
+
+ ctx.shadowColor = 'RGBA(0,255, 0,0)';
+ _assertSame(ctx.shadowColor, 'rgba(0, 255, 0, 0)', "ctx.shadowColor", "'rgba(0, 255, 0, 0)'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.html
new file mode 100644
index 0000000000..52be5ad532
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowOffset.initial</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowOffset.initial</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.worker.js
new file mode 100644
index 0000000000..b7b399b371
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.initial.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowOffset.initial
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.html
new file mode 100644
index 0000000000..d789284b0a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowOffset.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowOffset.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = Infinity;
+ ctx.shadowOffsetY = Infinity;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = -Infinity;
+ ctx.shadowOffsetY = -Infinity;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = NaN;
+ ctx.shadowOffsetY = NaN;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = 'string';
+ ctx.shadowOffsetY = 'string';
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = true;
+ ctx.shadowOffsetY = true;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 1, "ctx.shadowOffsetY", "1");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = false;
+ ctx.shadowOffsetY = false;
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.worker.js
new file mode 100644
index 0000000000..9eb89cd581
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.invalid.worker.js
@@ -0,0 +1,62 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowOffset.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = Infinity;
+ ctx.shadowOffsetY = Infinity;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = -Infinity;
+ ctx.shadowOffsetY = -Infinity;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = NaN;
+ ctx.shadowOffsetY = NaN;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = 'string';
+ ctx.shadowOffsetY = 'string';
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = true;
+ ctx.shadowOffsetY = true;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 1, "ctx.shadowOffsetY", "1");
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = false;
+ ctx.shadowOffsetY = false;
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.html
new file mode 100644
index 0000000000..82f5f0118d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.attributes.shadowOffset.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.attributes.shadowOffset.valid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 0.5;
+ ctx.shadowOffsetY = 0.25;
+ _assertSame(ctx.shadowOffsetX, 0.5, "ctx.shadowOffsetX", "0.5");
+ _assertSame(ctx.shadowOffsetY, 0.25, "ctx.shadowOffsetY", "0.25");
+
+ ctx.shadowOffsetX = -0.5;
+ ctx.shadowOffsetY = -0.25;
+ _assertSame(ctx.shadowOffsetX, -0.5, "ctx.shadowOffsetX", "-0.5");
+ _assertSame(ctx.shadowOffsetY, -0.25, "ctx.shadowOffsetY", "-0.25");
+
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 0;
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+
+ ctx.shadowOffsetX = 1e6;
+ ctx.shadowOffsetY = 1e6;
+ _assertSame(ctx.shadowOffsetX, 1e6, "ctx.shadowOffsetX", "1e6");
+ _assertSame(ctx.shadowOffsetY, 1e6, "ctx.shadowOffsetY", "1e6");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.worker.js
new file mode 100644
index 0000000000..5881c5bca5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.attributes.shadowOffset.valid.worker.js
@@ -0,0 +1,45 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.attributes.shadowOffset.valid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ _assertSame(ctx.shadowOffsetX, 1, "ctx.shadowOffsetX", "1");
+ _assertSame(ctx.shadowOffsetY, 2, "ctx.shadowOffsetY", "2");
+
+ ctx.shadowOffsetX = 0.5;
+ ctx.shadowOffsetY = 0.25;
+ _assertSame(ctx.shadowOffsetX, 0.5, "ctx.shadowOffsetX", "0.5");
+ _assertSame(ctx.shadowOffsetY, 0.25, "ctx.shadowOffsetY", "0.25");
+
+ ctx.shadowOffsetX = -0.5;
+ ctx.shadowOffsetY = -0.25;
+ _assertSame(ctx.shadowOffsetX, -0.5, "ctx.shadowOffsetX", "-0.5");
+ _assertSame(ctx.shadowOffsetY, -0.25, "ctx.shadowOffsetY", "-0.25");
+
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 0;
+ _assertSame(ctx.shadowOffsetX, 0, "ctx.shadowOffsetX", "0");
+ _assertSame(ctx.shadowOffsetY, 0, "ctx.shadowOffsetY", "0");
+
+ ctx.shadowOffsetX = 1e6;
+ ctx.shadowOffsetY = 1e6;
+ _assertSame(ctx.shadowOffsetX, 1e6, "ctx.shadowOffsetX", "1e6");
+ _assertSame(ctx.shadowOffsetY, 1e6, "ctx.shadowOffsetY", "1e6");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.html
new file mode 100644
index 0000000000..46c5032448
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.blur.high</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.blur.high</h1>
+<p class="desc">Shadows look correct for large blurs</p>
+
+
+<script>
+var t = async_test("Shadows look correct for large blurs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 0;
+ ctx.shadowBlur = 100;
+ ctx.fillRect(-200, -200, 200, 400);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.worker.js
new file mode 100644
index 0000000000..8bd06da381
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high-manual.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.blur.high
+// Description:Shadows look correct for large blurs
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows look correct for large blurs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 0;
+ ctx.shadowBlur = 100;
+ ctx.fillRect(-200, -200, 200, 400);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high.png
new file mode 100644
index 0000000000..743640b79f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.high.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.html
new file mode 100644
index 0000000000..19a42a683c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.blur.low</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.blur.low</h1>
+<p class="desc">Shadows look correct for small blurs</p>
+
+
+<script>
+var t = async_test("Shadows look correct for small blurs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 25;
+ for (var x = 0; x < 100; ++x) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(x, 0, 1, 50);
+ ctx.clip();
+ ctx.shadowBlur = x;
+ ctx.fillRect(-200, -200, 500, 200);
+ ctx.restore();
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.worker.js
new file mode 100644
index 0000000000..67bc8c424e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low-manual.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.blur.low
+// Description:Shadows look correct for small blurs
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows look correct for small blurs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 25;
+ for (var x = 0; x < 100; ++x) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(x, 0, 1, 50);
+ ctx.clip();
+ ctx.shadowBlur = x;
+ ctx.fillRect(-200, -200, 500, 200);
+ ctx.restore();
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low.png
new file mode 100644
index 0000000000..99fb651c21
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.blur.low.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.html
new file mode 100644
index 0000000000..cae4235e8c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.canvas.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.canvas.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent canvases</p>
+
+
+<script>
+var t = async_test("Shadows are drawn correctly for partially-transparent canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = 'rgba(255, 0, 0, 0.5)';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.worker.js
new file mode 100644
index 0000000000..0fa74a2070
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.alpha.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.canvas.alpha
+// Description:Shadows are drawn correctly for partially-transparent canvases
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn correctly for partially-transparent canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = 'rgba(255, 0, 0, 0.5)';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.html
new file mode 100644
index 0000000000..f5784e914f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.canvas.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.canvas.basic</h1>
+<p class="desc">Shadows are drawn for canvases</p>
+
+
+<script>
+var t = async_test("Shadows are drawn for canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.worker.js
new file mode 100644
index 0000000000..6a2d916a75
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.basic.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.canvas.basic
+// Description:Shadows are drawn for canvases
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn for canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.html
new file mode 100644
index 0000000000..62b3f83272
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.canvas.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.canvas.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent canvases</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn for transparent canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.worker.js
new file mode 100644
index 0000000000..1b02897d62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.1.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.canvas.transparent.1
+// Description:Shadows are not drawn for transparent canvases
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn for transparent canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.html
new file mode 100644
index 0000000000..0f80453523
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.canvas.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.canvas.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of canvases</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn for transparent parts of canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.drawImage(canvas2, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(canvas2, -50, -50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.worker.js
new file mode 100644
index 0000000000..6e468e28e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.canvas.transparent.2.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.canvas.transparent.2
+// Description:Shadows are not drawn for transparent parts of canvases
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn for transparent parts of canvases");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.drawImage(canvas2, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(canvas2, -50, -50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.html
new file mode 100644
index 0000000000..4df101d513
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.clip.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.clip.1</h1>
+<p class="desc">Shadows of clipped shapes are still drawn within the clipping region</p>
+
+
+<script>
+var t = async_test("Shadows of clipped shapes are still drawn within the clipping region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.worker.js
new file mode 100644
index 0000000000..6b05ceb226
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.1.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.clip.1
+// Description:Shadows of clipped shapes are still drawn within the clipping region
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows of clipped shapes are still drawn within the clipping region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.html
new file mode 100644
index 0000000000..6a09ea53f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.clip.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.clip.2</h1>
+<p class="desc">Shadows are not drawn outside the clipping region</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn outside the clipping region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.worker.js
new file mode 100644
index 0000000000..4cdfcfdcfc
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.2.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.clip.2
+// Description:Shadows are not drawn outside the clipping region
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn outside the clipping region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.html
new file mode 100644
index 0000000000..d1732e9f5b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.clip.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.clip.3</h1>
+<p class="desc">Shadows of clipped shapes are still drawn within the clipping region</p>
+
+
+<script>
+var t = async_test("Shadows of clipped shapes are still drawn within the clipping region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.worker.js
new file mode 100644
index 0000000000..6f8b79d1fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.clip.3.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.clip.3
+// Description:Shadows of clipped shapes are still drawn within the clipping region
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows of clipped shapes are still drawn within the clipping region");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.html
new file mode 100644
index 0000000000..d6014fbd45
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.composite.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.composite.1</h1>
+<p class="desc">Shadows are drawn using globalCompositeOperation</p>
+
+
+<script>
+var t = async_test("Shadows are drawn using globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, 0, 200, 50);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.worker.js
new file mode 100644
index 0000000000..28637706e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.composite.1
+// Description:Shadows are drawn using globalCompositeOperation
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn using globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, 0, 200, 50);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.html
new file mode 100644
index 0000000000..87f2e3ba0f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.composite.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.composite.2</h1>
+<p class="desc">Shadows are drawn using globalCompositeOperation</p>
+
+
+<script>
+var t = async_test("Shadows are drawn using globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-10, -10, 120, 70);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.worker.js
new file mode 100644
index 0000000000..a144446ec5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.composite.2
+// Description:Shadows are drawn using globalCompositeOperation
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn using globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-10, -10, 120, 70);
+
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.html
new file mode 100644
index 0000000000..f3cafa983a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.composite.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.composite.3</h1>
+<p class="desc">Areas outside shadows are drawn correctly with destination-out</p>
+
+
+<script>
+var t = async_test("Areas outside shadows are drawn correctly with destination-out");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 10;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(200, 0, 100, 50);
+
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.worker.js
new file mode 100644
index 0000000000..ba29487eea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.composite.3.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.composite.3
+// Description:Areas outside shadows are drawn correctly with destination-out
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Areas outside shadows are drawn correctly with destination-out");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 10;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(200, 0, 100, 50);
+
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.html
new file mode 100644
index 0000000000..a25be8ebcf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.enable.blur</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.enable.blur</h1>
+<p class="desc">Shadows are drawn if shadowBlur is set</p>
+
+
+<script>
+var t = async_test("Shadows are drawn if shadowBlur is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.worker.js
new file mode 100644
index 0000000000..859ae8b612
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.enable.blur
+// Description:Shadows are drawn if shadowBlur is set
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn if shadowBlur is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.html
new file mode 100644
index 0000000000..de85b7366b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.enable.off.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.enable.off.1</h1>
+<p class="desc">Shadows are not drawn when only shadowColor is set</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn when only shadowColor is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.worker.js
new file mode 100644
index 0000000000..7ccd1351fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.1.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.enable.off.1
+// Description:Shadows are not drawn when only shadowColor is set
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn when only shadowColor is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.html
new file mode 100644
index 0000000000..a57cb66aff
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.enable.off.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.enable.off.2</h1>
+<p class="desc">Shadows are not drawn when only shadowColor is set</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn when only shadowColor is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.worker.js
new file mode 100644
index 0000000000..e068a7ab54
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.off.2.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.enable.off.2
+// Description:Shadows are not drawn when only shadowColor is set
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn when only shadowColor is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.html
new file mode 100644
index 0000000000..70b0a84dcf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.enable.x</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.enable.x</h1>
+<p class="desc">Shadows are drawn if shadowOffsetX is set</p>
+
+
+<script>
+var t = async_test("Shadows are drawn if shadowOffsetX is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.worker.js
new file mode 100644
index 0000000000..975c621ffa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.enable.x
+// Description:Shadows are drawn if shadowOffsetX is set
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn if shadowOffsetX is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.html
new file mode 100644
index 0000000000..df8bcc2ba2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.enable.y</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.enable.y</h1>
+<p class="desc">Shadows are drawn if shadowOffsetY is set</p>
+
+
+<script>
+var t = async_test("Shadows are drawn if shadowOffsetY is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.worker.js
new file mode 100644
index 0000000000..1dae1000a3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.enable.y
+// Description:Shadows are drawn if shadowOffsetY is set
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn if shadowOffsetY is set");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.html
new file mode 100644
index 0000000000..199dd6c3fa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.gradient.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.gradient.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent gradient fills</p>
+
+
+<script>
+var t = async_test("Shadows are drawn correctly for partially-transparent gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(255,0,0,0.5)');
+ gradient.addColorStop(1, 'rgba(255,0,0,0.5)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.worker.js
new file mode 100644
index 0000000000..0f9a6449c4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.alpha.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.gradient.alpha
+// Description:Shadows are drawn correctly for partially-transparent gradient fills
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn correctly for partially-transparent gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(255,0,0,0.5)');
+ gradient.addColorStop(1, 'rgba(255,0,0,0.5)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.html
new file mode 100644
index 0000000000..6746f03f3d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.gradient.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.gradient.basic</h1>
+<p class="desc">Shadows are drawn for gradient fills</p>
+
+
+<script>
+var t = async_test("Shadows are drawn for gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(1, '#f00');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.worker.js
new file mode 100644
index 0000000000..068b48bb6f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.gradient.basic
+// Description:Shadows are drawn for gradient fills
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn for gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(1, '#f00');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.html
new file mode 100644
index 0000000000..7e7309e976
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.gradient.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.gradient.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent gradient fills</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn for transparent gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.worker.js
new file mode 100644
index 0000000000..1102848ecb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.1.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.gradient.transparent.1
+// Description:Shadows are not drawn for transparent gradient fills
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn for transparent gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.html
new file mode 100644
index 0000000000..8259eb9ae5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.gradient.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.gradient.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of gradient fills</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn for transparent parts of gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(0.499, '#f00');
+ gradient.addColorStop(0.5, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.worker.js
new file mode 100644
index 0000000000..5fcf4ee93d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.transparent.2.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.gradient.transparent.2
+// Description:Shadows are not drawn for transparent parts of gradient fills
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn for transparent parts of gradient fills");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(0.499, '#f00');
+ gradient.addColorStop(0.5, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.html
new file mode 100644
index 0000000000..f7f797fd0b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.image.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.image.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent images</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ var response = await fetch('/images/transparent50.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+}, "Shadows are drawn correctly for partially-transparent images");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.worker.js
new file mode 100644
index 0000000000..827bd2ce65
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.image.alpha
+// Description:Shadows are drawn correctly for partially-transparent images
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ var response = await fetch('/images/transparent50.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+}, "Shadows are drawn correctly for partially-transparent images");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.html
new file mode 100644
index 0000000000..5b959fdd92
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.image.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.image.basic</h1>
+<p class="desc">Shadows are drawn for images</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+}, "Shadows are drawn for images");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.worker.js
new file mode 100644
index 0000000000..2d02232c68
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.image.basic
+// Description:Shadows are drawn for images
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+}, "Shadows are drawn for images");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.html
new file mode 100644
index 0000000000..7e2536c052
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.image.scale</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.image.scale</h1>
+<p class="desc">Shadows are drawn correctly for scaled images</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, 0, 100, 50, -10, -50, 240, 50);
+
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Shadows are drawn correctly for scaled images");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.worker.js
new file mode 100644
index 0000000000..2c10381f98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.image.scale
+// Description:Shadows are drawn correctly for scaled images
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, 0, 100, 50, -10, -50, 240, 50);
+
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Shadows are drawn correctly for scaled images");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.html
new file mode 100644
index 0000000000..7744ee153b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.image.section</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.image.section</h1>
+<p class="desc">Shadows are not drawn for areas outside image source rectangles</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#f00';
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 50, 0, 50, 50, 0, -50, 50, 50);
+
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Shadows are not drawn for areas outside image source rectangles");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.worker.js
new file mode 100644
index 0000000000..94affdfb6a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.section.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.image.section
+// Description:Shadows are not drawn for areas outside image source rectangles
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#f00';
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 50, 0, 50, 50, 0, -50, 50, 50);
+
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Shadows are not drawn for areas outside image source rectangles");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.html
new file mode 100644
index 0000000000..30db23ce76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.image.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.image.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent images</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ var response = await fetch('/images/transparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+}, "Shadows are not drawn for transparent images");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.worker.js
new file mode 100644
index 0000000000..c5421d7042
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.1.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.image.transparent.1
+// Description:Shadows are not drawn for transparent images
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ var response = await fetch('/images/transparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 0, -50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+}, "Shadows are not drawn for transparent images");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.html
new file mode 100644
index 0000000000..9b3b206a26
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.image.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.image.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of images</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(img, -50, -50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+}, "Shadows are not drawn for transparent parts of images");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.worker.js
new file mode 100644
index 0000000000..071c584fa8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.image.transparent.2
+// Description:Shadows are not drawn for transparent parts of images
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ ctx.drawImage(img, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(img, -50, -50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+}, "Shadows are not drawn for transparent parts of images");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.html
new file mode 100644
index 0000000000..cc0d1adb97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.offset.negativeX</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.offset.negativeX</h1>
+<p class="desc">Shadows can be offset with negative x</p>
+
+
+<script>
+var t = async_test("Shadows can be offset with negative x");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = -50;
+ ctx.fillRect(50, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.worker.js
new file mode 100644
index 0000000000..14c709a2a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeX.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.offset.negativeX
+// Description:Shadows can be offset with negative x
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows can be offset with negative x");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = -50;
+ ctx.fillRect(50, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.html
new file mode 100644
index 0000000000..82094cf2f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.offset.negativeY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.offset.negativeY</h1>
+<p class="desc">Shadows can be offset with negative y</p>
+
+
+<script>
+var t = async_test("Shadows can be offset with negative y");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = -25;
+ ctx.fillRect(0, 25, 100, 25);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.worker.js
new file mode 100644
index 0000000000..036c6154cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.negativeY.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.offset.negativeY
+// Description:Shadows can be offset with negative y
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows can be offset with negative y");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = -25;
+ ctx.fillRect(0, 25, 100, 25);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.html
new file mode 100644
index 0000000000..7094e98ecf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.offset.positiveX</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.offset.positiveX</h1>
+<p class="desc">Shadows can be offset with positive x</p>
+
+
+<script>
+var t = async_test("Shadows can be offset with positive x");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.worker.js
new file mode 100644
index 0000000000..176aca45f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveX.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.offset.positiveX
+// Description:Shadows can be offset with positive x
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows can be offset with positive x");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.html
new file mode 100644
index 0000000000..75e9b0affa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.offset.positiveY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.offset.positiveY</h1>
+<p class="desc">Shadows can be offset with positive y</p>
+
+
+<script>
+var t = async_test("Shadows can be offset with positive y");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 25;
+ ctx.fillRect(0, 0, 100, 25);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.worker.js
new file mode 100644
index 0000000000..6b4d0c6a21
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.offset.positiveY.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.offset.positiveY
+// Description:Shadows can be offset with positive y
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows can be offset with positive y");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 25;
+ ctx.fillRect(0, 0, 100, 25);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.html
new file mode 100644
index 0000000000..498051465b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.outside</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.outside</h1>
+<p class="desc">Shadows of shapes outside the visible area can be offset onto the visible area</p>
+
+
+<script>
+var t = async_test("Shadows of shapes outside the visible area can be offset onto the visible area");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.fillRect(-100, 0, 25, 50);
+ ctx.shadowOffsetX = -100;
+ ctx.fillRect(175, 0, 25, 50);
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 100;
+ ctx.fillRect(25, -100, 50, 25);
+ ctx.shadowOffsetY = -100;
+ ctx.fillRect(25, 125, 50, 25);
+ _assertPixel(canvas, 12,25, 0,255,0,255);
+ _assertPixel(canvas, 87,25, 0,255,0,255);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.worker.js
new file mode 100644
index 0000000000..d2a071f474
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.outside.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.outside
+// Description:Shadows of shapes outside the visible area can be offset onto the visible area
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows of shapes outside the visible area can be offset onto the visible area");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.fillRect(-100, 0, 25, 50);
+ ctx.shadowOffsetX = -100;
+ ctx.fillRect(175, 0, 25, 50);
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 100;
+ ctx.fillRect(25, -100, 50, 25);
+ ctx.shadowOffsetY = -100;
+ ctx.fillRect(25, 125, 50, 25);
+ _assertPixel(canvas, 12,25, 0,255,0,255);
+ _assertPixel(canvas, 87,25, 0,255,0,255);
+ _assertPixel(canvas, 50,12, 0,255,0,255);
+ _assertPixel(canvas, 50,37, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.html
new file mode 100644
index 0000000000..c45654f999
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.pattern.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.pattern.alpha</h1>
+<p class="desc">Shadows are drawn correctly for partially-transparent fill patterns</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/transparent50.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+
+}, "Shadows are drawn correctly for partially-transparent fill patterns");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.png b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.png
new file mode 100644
index 0000000000..8764e89b37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.worker.js
new file mode 100644
index 0000000000..41a826a158
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.alpha.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.pattern.alpha
+// Description:Shadows are drawn correctly for partially-transparent fill patterns
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/transparent50.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixelApprox(canvas, 50,25, 127,0,127,255, 2);
+ t.done();
+}, "Shadows are drawn correctly for partially-transparent fill patterns");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.html
new file mode 100644
index 0000000000..4e372c0932
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.pattern.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.pattern.basic</h1>
+<p class="desc">Shadows are drawn for fill patterns</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+}, "Shadows are drawn for fill patterns");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.worker.js
new file mode 100644
index 0000000000..7a8f7e8479
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.basic.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.pattern.basic
+// Description:Shadows are drawn for fill patterns
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/red.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+}, "Shadows are drawn for fill patterns");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.html
new file mode 100644
index 0000000000..72fa7b29f8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.pattern.transparent.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.pattern.transparent.1</h1>
+<p class="desc">Shadows are not drawn for transparent fill patterns</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/transparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+
+}, "Shadows are not drawn for transparent fill patterns");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.worker.js
new file mode 100644
index 0000000000..8414db6d08
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.1.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.pattern.transparent.1
+// Description:Shadows are not drawn for transparent fill patterns
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/transparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+}, "Shadows are not drawn for transparent fill patterns");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.html
new file mode 100644
index 0000000000..6ad8ece009
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.pattern.transparent.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.pattern.transparent.2</h1>
+<p class="desc">Shadows are not drawn for transparent parts of fill patterns</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+
+}, "Shadows are not drawn for transparent parts of fill patterns");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.worker.js
new file mode 100644
index 0000000000..726a42d6cd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.pattern.transparent.2.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.pattern.transparent.2
+// Description:Shadows are not drawn for transparent parts of fill patterns
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var response = await fetch('/images/redtransparent.png')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+}, "Shadows are not drawn for transparent parts of fill patterns");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.html
new file mode 100644
index 0000000000..c569865a60
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.stroke.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.stroke.basic</h1>
+<p class="desc">Shadows are drawn for strokes</p>
+
+
+<script>
+var t = async_test("Shadows are drawn for strokes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, -25);
+ ctx.lineTo(100, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.worker.js
new file mode 100644
index 0000000000..9d7d0ec321
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.basic.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.stroke.basic
+// Description:Shadows are drawn for strokes
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn for strokes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, -25);
+ ctx.lineTo(100, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.html
new file mode 100644
index 0000000000..b170f88cf6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.stroke.cap.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.stroke.cap.1</h1>
+<p class="desc">Shadows are not drawn for areas outside stroke caps</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn for areas outside stroke caps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'butt';
+ ctx.moveTo(-50, -25);
+ ctx.lineTo(0, -25);
+ ctx.moveTo(100, -25);
+ ctx.lineTo(150, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.worker.js
new file mode 100644
index 0000000000..582915d28b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.1.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.stroke.cap.1
+// Description:Shadows are not drawn for areas outside stroke caps
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn for areas outside stroke caps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'butt';
+ ctx.moveTo(-50, -25);
+ ctx.lineTo(0, -25);
+ ctx.moveTo(100, -25);
+ ctx.lineTo(150, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.html
new file mode 100644
index 0000000000..8bbb016bd5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.stroke.cap.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.stroke.cap.2</h1>
+<p class="desc">Shadows are drawn for stroke caps</p>
+
+
+<script>
+var t = async_test("Shadows are drawn for stroke caps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'square';
+ ctx.moveTo(25, -25);
+ ctx.lineTo(75, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.worker.js
new file mode 100644
index 0000000000..13108bec9e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.cap.2.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.stroke.cap.2
+// Description:Shadows are drawn for stroke caps
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn for stroke caps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'square';
+ ctx.moveTo(25, -25);
+ ctx.lineTo(75, -25);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,25, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.html
new file mode 100644
index 0000000000..f0ef2d250e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.stroke.join.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.stroke.join.1</h1>
+<p class="desc">Shadows are not drawn for areas outside stroke joins</p>
+
+
+<script>
+var t = async_test("Shadows are not drawn for areas outside stroke joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.worker.js
new file mode 100644
index 0000000000..0cc1b5f196
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.1.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.stroke.join.1
+// Description:Shadows are not drawn for areas outside stroke joins
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are not drawn for areas outside stroke joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.html
new file mode 100644
index 0000000000..f2800aa19a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.stroke.join.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.stroke.join.2</h1>
+<p class="desc">Shadows are drawn for stroke joins</p>
+
+
+<script>
+var t = async_test("Shadows are drawn for stroke joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.worker.js
new file mode 100644
index 0000000000..925f65a28e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.2.worker.js
@@ -0,0 +1,40 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.stroke.join.2
+// Description:Shadows are drawn for stroke joins
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn for stroke joins");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.html
new file mode 100644
index 0000000000..390e6a8048
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.stroke.join.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.stroke.join.3</h1>
+<p class="desc">Shadows are drawn for stroke joins respecting miter limit</p>
+
+
+<script>
+var t = async_test("Shadows are drawn for stroke joins respecting miter limit");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 0.1;
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100); // (not an exact right angle, to avoid some other bug in Firefox 3)
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.worker.js
new file mode 100644
index 0000000000..827a6d6662
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.stroke.join.3.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.stroke.join.3
+// Description:Shadows are drawn for stroke joins respecting miter limit
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows are drawn for stroke joins respecting miter limit");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 0.1;
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100); // (not an exact right angle, to avoid some other bug in Firefox 3)
+ ctx.stroke();
+
+ _assertPixel(canvas, 1,1, 0,255,0,255);
+ _assertPixel(canvas, 48,48, 0,255,0,255);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,48, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.html
new file mode 100644
index 0000000000..23946b20a5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.transform.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.transform.1</h1>
+<p class="desc">Shadows take account of transformations</p>
+
+
+<script>
+var t = async_test("Shadows take account of transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.translate(100, 100);
+ ctx.fillRect(-100, -150, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.worker.js
new file mode 100644
index 0000000000..6ac8da4c97
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.1.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.transform.1
+// Description:Shadows take account of transformations
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadows take account of transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.translate(100, 100);
+ ctx.fillRect(-100, -150, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.html b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.html
new file mode 100644
index 0000000000..edcd20bdca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.shadow.transform.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.shadow.transform.2</h1>
+<p class="desc">Shadow offsets are not affected by transformations</p>
+
+
+<script>
+var t = async_test("Shadow offsets are not affected by transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.rotate(Math.PI)
+ ctx.fillRect(-100, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.worker.js
new file mode 100644
index 0000000000..e9e745a2ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.transform.2.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.shadow.transform.2
+// Description:Shadow offsets are not affected by transformations
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Shadow offsets are not affected by transformations");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.rotate(Math.PI)
+ ctx.fillRect(-100, 0, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.html
new file mode 100644
index 0000000000..7af2c772f0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.align.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.align.default</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.worker.js
new file mode 100644
index 0000000000..adee16c062
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.default.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.align.default
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.html
new file mode 100644
index 0000000000..a7679d656e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.align.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.align.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'bogus';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'END';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end ';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end\0';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.worker.js
new file mode 100644
index 0000000000..dfd4c66256
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.invalid.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.align.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'bogus';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'END';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end ';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end\0';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.html
new file mode 100644
index 0000000000..eef6b29633
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.align.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.align.valid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textAlign = 'start';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'end';
+ _assertSame(ctx.textAlign, 'end', "ctx.textAlign", "'end'");
+
+ ctx.textAlign = 'left';
+ _assertSame(ctx.textAlign, 'left', "ctx.textAlign", "'left'");
+
+ ctx.textAlign = 'right';
+ _assertSame(ctx.textAlign, 'right', "ctx.textAlign", "'right'");
+
+ ctx.textAlign = 'center';
+ _assertSame(ctx.textAlign, 'center', "ctx.textAlign", "'center'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.worker.js
new file mode 100644
index 0000000000..767d6425e7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.align.valid.worker.js
@@ -0,0 +1,35 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.align.valid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textAlign = 'start';
+ _assertSame(ctx.textAlign, 'start', "ctx.textAlign", "'start'");
+
+ ctx.textAlign = 'end';
+ _assertSame(ctx.textAlign, 'end', "ctx.textAlign", "'end'");
+
+ ctx.textAlign = 'left';
+ _assertSame(ctx.textAlign, 'left', "ctx.textAlign", "'left'");
+
+ ctx.textAlign = 'right';
+ _assertSame(ctx.textAlign, 'right', "ctx.textAlign", "'right'");
+
+ ctx.textAlign = 'center';
+ _assertSame(ctx.textAlign, 'center', "ctx.textAlign", "'center'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.html
new file mode 100644
index 0000000000..525a02ff9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.baseline.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.baseline.default</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.textBaseline, 'alphabetic', "ctx.textBaseline", "'alphabetic'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.worker.js
new file mode 100644
index 0000000000..667adb8c51
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.default.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.baseline.default
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.textBaseline, 'alphabetic', "ctx.textBaseline", "'alphabetic'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.html
new file mode 100644
index 0000000000..f30fad63b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.baseline.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.baseline.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'bogus';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'MIDDLE';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle ';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle\0';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.worker.js
new file mode 100644
index 0000000000..4310f81fba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.invalid.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.baseline.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'bogus';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'MIDDLE';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle ';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle\0';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.html
new file mode 100644
index 0000000000..9ff843c19f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.baseline.valid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.baseline.valid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textBaseline = 'top';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'hanging';
+ _assertSame(ctx.textBaseline, 'hanging', "ctx.textBaseline", "'hanging'");
+
+ ctx.textBaseline = 'middle';
+ _assertSame(ctx.textBaseline, 'middle', "ctx.textBaseline", "'middle'");
+
+ ctx.textBaseline = 'alphabetic';
+ _assertSame(ctx.textBaseline, 'alphabetic', "ctx.textBaseline", "'alphabetic'");
+
+ ctx.textBaseline = 'ideographic';
+ _assertSame(ctx.textBaseline, 'ideographic', "ctx.textBaseline", "'ideographic'");
+
+ ctx.textBaseline = 'bottom';
+ _assertSame(ctx.textBaseline, 'bottom', "ctx.textBaseline", "'bottom'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.worker.js
new file mode 100644
index 0000000000..2f422f58a8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.baseline.valid.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.baseline.valid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textBaseline = 'top';
+ _assertSame(ctx.textBaseline, 'top', "ctx.textBaseline", "'top'");
+
+ ctx.textBaseline = 'hanging';
+ _assertSame(ctx.textBaseline, 'hanging', "ctx.textBaseline", "'hanging'");
+
+ ctx.textBaseline = 'middle';
+ _assertSame(ctx.textBaseline, 'middle', "ctx.textBaseline", "'middle'");
+
+ ctx.textBaseline = 'alphabetic';
+ _assertSame(ctx.textBaseline, 'alphabetic', "ctx.textBaseline", "'alphabetic'");
+
+ ctx.textBaseline = 'ideographic';
+ _assertSame(ctx.textBaseline, 'ideographic', "ctx.textBaseline", "'ideographic'");
+
+ ctx.textBaseline = 'bottom';
+ _assertSame(ctx.textBaseline, 'bottom', "ctx.textBaseline", "'bottom'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.html
new file mode 100644
index 0000000000..0f7a2f4a02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.align.center</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.align.center</h1>
+<p class="desc">textAlign center is the center of the em squares (not the bounding box)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'center';
+ ctx.fillText('DD', 50, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign center is the center of the em squares (not the bounding box)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.worker.js
new file mode 100644
index 0000000000..44f093cdac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.center.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.align.center
+// Description:textAlign center is the center of the em squares (not the bounding box)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'center';
+ ctx.fillText('DD', 50, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textAlign center is the center of the em squares (not the bounding box)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.html
new file mode 100644
index 0000000000..a9e6dfe901
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.align.end.ltr</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.align.end.ltr</h1>
+<p class="desc">textAlign end with ltr is the right edge</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign end with ltr is the right edge");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.worker.js
new file mode 100644
index 0000000000..4bd0f5a314
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.ltr.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.align.end.ltr
+// Description:textAlign end with ltr is the right edge
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textAlign end with ltr is the right edge");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.html
new file mode 100644
index 0000000000..b0d0b66a9c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.align.end.rtl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.align.end.rtl</h1>
+<p class="desc">textAlign end with rtl is the left edge</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'rtl';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign end with rtl is the left edge");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.worker.js
new file mode 100644
index 0000000000..b3e62d8538
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.end.rtl.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.align.end.rtl
+// Description:textAlign end with rtl is the left edge
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'rtl';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textAlign end with rtl is the left edge");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.html
new file mode 100644
index 0000000000..563596d757
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.align.left</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.align.left</h1>
+<p class="desc">textAlign left is the left of the first em square (not the bounding box)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'left';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign left is the left of the first em square (not the bounding box)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.worker.js
new file mode 100644
index 0000000000..c7dc0bed42
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.left.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.align.left
+// Description:textAlign left is the left of the first em square (not the bounding box)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'left';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textAlign left is the left of the first em square (not the bounding box)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.html
new file mode 100644
index 0000000000..227a8f981f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.align.right</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.align.right</h1>
+<p class="desc">textAlign right is the right of the last em square (not the bounding box)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign right is the right of the last em square (not the bounding box)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.worker.js
new file mode 100644
index 0000000000..58fe85e0b7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.right.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.align.right
+// Description:textAlign right is the right of the last em square (not the bounding box)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textAlign right is the right of the last em square (not the bounding box)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.html
new file mode 100644
index 0000000000..bd7e69451d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.align.start.ltr</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.align.start.ltr</h1>
+<p class="desc">textAlign start with ltr is the left edge</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign start with ltr is the left edge");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.worker.js
new file mode 100644
index 0000000000..c0793d9af6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.ltr.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.align.start.ltr
+// Description:textAlign start with ltr is the left edge
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textAlign start with ltr is the left edge");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.html
new file mode 100644
index 0000000000..cadc8a4644
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.align.start.rtl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.align.start.rtl</h1>
+<p class="desc">textAlign start with rtl is the right edge</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'rtl';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textAlign start with rtl is the right edge");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.worker.js
new file mode 100644
index 0000000000..ed706c287a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.align.start.rtl.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.align.start.rtl
+// Description:textAlign start with rtl is the right edge
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'rtl';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 100, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textAlign start with rtl is the right edge");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.html
new file mode 100644
index 0000000000..ff72b3219d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.baseline.alphabetic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.baseline.alphabetic</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'alphabetic';
+ ctx.fillText('CC', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.worker.js
new file mode 100644
index 0000000000..a98a5863d9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.alphabetic.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.baseline.alphabetic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'alphabetic';
+ ctx.fillText('CC', 0, 37.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.html
new file mode 100644
index 0000000000..f75a94243d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.baseline.bottom</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.baseline.bottom</h1>
+<p class="desc">textBaseline bottom is the bottom of the em square (not the bounding box)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'bottom';
+ ctx.fillText('CC', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textBaseline bottom is the bottom of the em square (not the bounding box)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.worker.js
new file mode 100644
index 0000000000..30f60c574b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.bottom.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.baseline.bottom
+// Description:textBaseline bottom is the bottom of the em square (not the bounding box)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'bottom';
+ ctx.fillText('CC', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textBaseline bottom is the bottom of the em square (not the bounding box)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.html
new file mode 100644
index 0000000000..a29db78385
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.baseline.hanging</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.baseline.hanging</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'hanging';
+ ctx.fillText('CC', 0, 12.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.worker.js
new file mode 100644
index 0000000000..638506a279
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.hanging.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.baseline.hanging
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'hanging';
+ ctx.fillText('CC', 0, 12.5);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.html
new file mode 100644
index 0000000000..6bda1b4f30
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.baseline.ideographic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.baseline.ideographic</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'ideographic';
+ ctx.fillText('CC', 0, 31.25);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.worker.js
new file mode 100644
index 0000000000..7c682fb5f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.ideographic.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.baseline.ideographic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'ideographic';
+ ctx.fillText('CC', 0, 31.25);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.html
new file mode 100644
index 0000000000..b0186e6549
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.baseline.middle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.baseline.middle</h1>
+<p class="desc">textBaseline middle is the middle of the em square (not the bounding box)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'middle';
+ ctx.fillText('CC', 0, 25);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textBaseline middle is the middle of the em square (not the bounding box)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.worker.js
new file mode 100644
index 0000000000..c373ab6c72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.middle.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.baseline.middle
+// Description:textBaseline middle is the middle of the em square (not the bounding box)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'middle';
+ ctx.fillText('CC', 0, 25);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textBaseline middle is the middle of the em square (not the bounding box)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.html
new file mode 100644
index 0000000000..163d27dec7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.baseline.top</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.baseline.top</h1>
+<p class="desc">textBaseline top is the top of the em square (not the bounding box)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'top';
+ ctx.fillText('CC', 0, 0);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+
+}, "textBaseline top is the top of the em square (not the bounding box)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.worker.js
new file mode 100644
index 0000000000..effc4418c3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.baseline.top.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.baseline.top
+// Description:textBaseline top is the top of the em square (not the bounding box)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'top';
+ ctx.fillText('CC', 0, 0);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 5,45, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,45, 0,255,0,255, 2);
+ t.done();
+}, "textBaseline top is the top of the em square (not the bounding box)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.html
new file mode 100644
index 0000000000..af1cb9d94a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.basic</h1>
+<p class="desc">fillText draws filled text</p>
+
+
+<script>
+var t = async_test("fillText draws filled text");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.worker.js
new file mode 100644
index 0000000000..ef00236fbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic-manual.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.basic
+// Description:fillText draws filled text
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText draws filled text");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.png b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.png
new file mode 100644
index 0000000000..70d7b046cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.basic.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.html
new file mode 100644
index 0000000000..8f22b9f093
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.maxWidth.NaN</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.maxWidth.NaN</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, NaN);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.worker.js
new file mode 100644
index 0000000000..fd1dff136e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.NaN.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.maxWidth.NaN
+// Description:fillText handles maxWidth correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, NaN);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.html
new file mode 100644
index 0000000000..2dca5a75ef
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.maxWidth.bound</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.maxWidth.bound</h1>
+<p class="desc">fillText handles maxWidth based on line size, not bounding box size</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('DD', 0, 37.5, 100);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "fillText handles maxWidth based on line size, not bounding box size");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.worker.js
new file mode 100644
index 0000000000..adcb45faaa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.bound.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.maxWidth.bound
+// Description:fillText handles maxWidth based on line size, not bounding box size
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('DD', 0, 37.5, 100);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "fillText handles maxWidth based on line size, not bounding box size");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.html
new file mode 100644
index 0000000000..fa7277ed7a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.maxWidth.fontface</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.maxWidth.fontface</h1>
+<p class="desc">fillText works on @font-face fonts</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillText('EEEE', -50, 37.5, 40);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "fillText works on @font-face fonts");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.worker.js
new file mode 100644
index 0000000000..8df519b7d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.fontface.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.maxWidth.fontface
+// Description:fillText works on @font-face fonts
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillText('EEEE', -50, 37.5, 40);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "fillText works on @font-face fonts");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.html
new file mode 100644
index 0000000000..7a0cf11b39
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.maxWidth.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.maxWidth.large</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35, 200);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.worker.js
new file mode 100644
index 0000000000..3e200e89ed
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large-manual.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.maxWidth.large
+// Description:fillText handles maxWidth correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35, 200);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.png b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.png
new file mode 100644
index 0000000000..70d7b046cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.large.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.html
new file mode 100644
index 0000000000..4411fbfced
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.maxWidth.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.maxWidth.negative</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, -1);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.worker.js
new file mode 100644
index 0000000000..50076b524c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.negative.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.maxWidth.negative
+// Description:fillText handles maxWidth correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, -1);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.html
new file mode 100644
index 0000000000..94988fc92e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.maxWidth.small</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.maxWidth.small</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', -100, 35, 90);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.worker.js
new file mode 100644
index 0000000000..5d5ef4e391
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.small.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.maxWidth.small
+// Description:fillText handles maxWidth correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', -100, 35, 90);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.html
new file mode 100644
index 0000000000..a789a84dbe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.maxWidth.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.maxWidth.zero</h1>
+<p class="desc">fillText handles maxWidth correctly</p>
+
+
+<script>
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, 0);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.worker.js
new file mode 100644
index 0000000000..7dea281f98
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.maxWidth.zero.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.maxWidth.zero
+// Description:fillText handles maxWidth correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText handles maxWidth correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, 0);
+ _assertGreen(ctx, 100, 50);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.html
new file mode 100644
index 0000000000..98e329b054
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.rtl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.rtl</h1>
+<p class="desc">fillText respects Right-To-Left Override characters</p>
+
+
+<script>
+var t = async_test("fillText respects Right-To-Left Override characters");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('\u202eFAIL \xa0 \xa0 SSAP', 5, 35);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.worker.js
new file mode 100644
index 0000000000..ee24a0450f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl-manual.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.rtl
+// Description:fillText respects Right-To-Left Override characters
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText respects Right-To-Left Override characters");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('\u202eFAIL \xa0 \xa0 SSAP', 5, 35);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.png b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.png
new file mode 100644
index 0000000000..70d7b046cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.rtl.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.html
new file mode 100644
index 0000000000..7124c6eafd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fill.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fill.unaffected</h1>
+<p class="desc">fillText does not start a new path or subpath</p>
+
+
+<script>
+var t = async_test("fillText does not start a new path or subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.worker.js
new file mode 100644
index 0000000000..0e250286d4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fill.unaffected.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fill.unaffected
+// Description:fillText does not start a new path or subpath
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("fillText does not start a new path or subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.html
new file mode 100644
index 0000000000..5d4f93b4f3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fontface</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fontface</h1>
+<p class="desc"></p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.html
new file mode 100644
index 0000000000..82c9b31e66
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fontface.notinpage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fontface.notinpage</h1>
+<p class="desc">@font-face fonts should work even if they are not used in the page</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "@font-face fonts should work even if they are not used in the page");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.worker.js
new file mode 100644
index 0000000000..628cb39506
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.notinpage.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fontface.notinpage
+// Description:@font-face fonts should work even if they are not used in the page
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "@font-face fonts should work even if they are not used in the page");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.html
new file mode 100644
index 0000000000..1a6ba78fb9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.fontface.repeat</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.fontface.repeat</h1>
+<p class="desc">Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+
+ await new Promise(resolve => t.step_timeout(resolve, 500));
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.worker.js
new file mode 100644
index 0000000000..7567c09558
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.repeat.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fontface.repeat
+// Description:Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+
+ await new Promise(resolve => t.step_timeout(resolve, 500));
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.worker.js
new file mode 100644
index 0000000000..02257f0a06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.fontface.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.fontface
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.html
new file mode 100644
index 0000000000..de456a2b96
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.kern.consistent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.kern.consistent</h1>
+<p class="desc">Stroked and filled text should have exactly the same kerning so it overlaps</p>
+
+
+<script>
+var t = async_test("Stroked and filled text should have exactly the same kerning so it overlaps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 3;
+ ctx.font = '20px Arial, sans-serif';
+ ctx.fillText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.fillText('ToToToToToToTo', -50, 45);
+ ctx.strokeText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.strokeText('ToToToToToToTo', -50, 45);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.worker.js
new file mode 100644
index 0000000000..0d1c9470ee
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.kern.consistent-manual.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.kern.consistent
+// Description:Stroked and filled text should have exactly the same kerning so it overlaps
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Stroked and filled text should have exactly the same kerning so it overlaps");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 3;
+ ctx.font = '20px Arial, sans-serif';
+ ctx.fillText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.fillText('ToToToToToToTo', -50, 45);
+ ctx.strokeText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.strokeText('ToToToToToToTo', -50, 45);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.html
new file mode 100644
index 0000000000..55828fc72c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.space.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.space.basic</h1>
+<p class="desc">U+0020 is rendered the correct size (1em wide)</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', -100, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "U+0020 is rendered the correct size (1em wide)");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.worker.js
new file mode 100644
index 0000000000..ef09925c55
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.basic.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.space.basic
+// Description:U+0020 is rendered the correct size (1em wide)
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', -100, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "U+0020 is rendered the correct size (1em wide)");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.html
new file mode 100644
index 0000000000..f00a187e23
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.space.collapse.end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.space.collapse.end</h1>
+<p class="desc">Space characters at the end of a line are NOT collapsed</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('EE ', 100, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+
+}, "Space characters at the end of a line are NOT collapsed");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.worker.js
new file mode 100644
index 0000000000..9a9afa1e74
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.end.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.space.collapse.end
+// Description:Space characters at the end of a line are NOT collapsed
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('EE ', 100, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+ t.done();
+}, "Space characters at the end of a line are NOT collapsed");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.html
new file mode 100644
index 0000000000..792abe4deb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.space.collapse.nonspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.space.collapse.nonspace</h1>
+<p class="desc">Non-space characters are not converted to U+0020 and collapsed</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E\x0b EE', -150, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Non-space characters are not converted to U+0020 and collapsed");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.worker.js
new file mode 100644
index 0000000000..a12c2f9a48
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.nonspace.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.space.collapse.nonspace
+// Description:Non-space characters are not converted to U+0020 and collapsed
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E\x0b EE', -150, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Non-space characters are not converted to U+0020 and collapsed");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.html
new file mode 100644
index 0000000000..83e89270f9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.space.collapse.other</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.space.collapse.other</h1>
+<p class="desc">Space characters are converted to U+0020, and are NOT collapsed</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dEE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+
+}, "Space characters are converted to U+0020, and are NOT collapsed");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.worker.js
new file mode 100644
index 0000000000..bbf9e684be
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.other.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.space.collapse.other
+// Description:Space characters are converted to U+0020, and are NOT collapsed
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dEE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+ t.done();
+}, "Space characters are converted to U+0020, and are NOT collapsed");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.html
new file mode 100644
index 0000000000..5fc96ffd7d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.space.collapse.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.space.collapse.space</h1>
+<p class="desc">Space characters are converted to U+0020, and are NOT collapsed</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+
+}, "Space characters are converted to U+0020, and are NOT collapsed");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.worker.js
new file mode 100644
index 0000000000..e5ab7b67f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.space.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.space.collapse.space
+// Description:Space characters are converted to U+0020, and are NOT collapsed
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 255,0,0,255, 2);
+ t.done();
+}, "Space characters are converted to U+0020, and are NOT collapsed");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.html
new file mode 100644
index 0000000000..c07994360d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.space.collapse.start</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.space.collapse.start</h1>
+<p class="desc">Space characters at the start of a line are NOT collapsed</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText(' EE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 255,0,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+
+}, "Space characters at the start of a line are NOT collapsed");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.worker.js
new file mode 100644
index 0000000000..20fec7801f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.space.collapse.start.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.space.collapse.start
+// Description:Space characters at the start of a line are NOT collapsed
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText(' EE', 0, 37.5);
+ _assertPixelApprox(canvas, 25,25, 255,0,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ t.done();
+}, "Space characters at the start of a line are NOT collapsed");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.html
new file mode 100644
index 0000000000..62ac8884cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.stroke.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.stroke.basic</h1>
+<p class="desc">strokeText draws stroked text</p>
+
+
+<script>
+var t = async_test("strokeText draws stroked text");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 1;
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeText('PASS', 5, 35);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.worker.js
new file mode 100644
index 0000000000..33d6e32467
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic-manual.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.stroke.basic
+// Description:strokeText draws stroked text
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeText draws stroked text");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 1;
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeText('PASS', 5, 35);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.png b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.png
new file mode 100644
index 0000000000..fb3b5b830d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.basic.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.html
new file mode 100644
index 0000000000..76afc1b006
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.draw.stroke.unaffected</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.draw.stroke.unaffected</h1>
+<p class="desc">strokeText does not start a new path or subpath</p>
+
+
+<script>
+var t = async_test("strokeText does not start a new path or subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeStyle = '#f00';
+ ctx.strokeText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.worker.js
new file mode 100644
index 0000000000..15c3b61700
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.draw.stroke.unaffected.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.draw.stroke.unaffected
+// Description:strokeText does not start a new path or subpath
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("strokeText does not start a new path or subpath");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeStyle = '#f00';
+ ctx.strokeText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 5,45, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.html
new file mode 100644
index 0000000000..965d451020
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.absolute.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.absolute.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with absolute length</p>
+
+
+<script>
+var t = async_test("Testing letter spacing and word spacing with absolute length");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.letterSpacing = '3px';
+ _assertSame(ctx.letterSpacing, '3px', "ctx.letterSpacing", "'3px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.wordSpacing = '5px';
+ _assertSame(ctx.letterSpacing, '3px', "ctx.letterSpacing", "'3px'");
+ _assertSame(ctx.wordSpacing, '5px', "ctx.wordSpacing", "'5px'");
+
+ ctx.letterSpacing = '-1px';
+ ctx.wordSpacing = '-1px';
+ _assertSame(ctx.letterSpacing, '-1px', "ctx.letterSpacing", "'-1px'");
+ _assertSame(ctx.wordSpacing, '-1px', "ctx.wordSpacing", "'-1px'");
+
+ ctx.letterSpacing = '1PX';
+ ctx.wordSpacing = '10PX';
+ _assertSame(ctx.letterSpacing, '1px', "ctx.letterSpacing", "'1px'");
+ _assertSame(ctx.wordSpacing, '10px', "ctx.wordSpacing", "'10px'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.worker.js
new file mode 100644
index 0000000000..2b42b3e477
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.absolute.spacing.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.absolute.spacing
+// Description:Testing letter spacing and word spacing with absolute length
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing letter spacing and word spacing with absolute length");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.letterSpacing = '3px';
+ _assertSame(ctx.letterSpacing, '3px', "ctx.letterSpacing", "'3px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.wordSpacing = '5px';
+ _assertSame(ctx.letterSpacing, '3px', "ctx.letterSpacing", "'3px'");
+ _assertSame(ctx.wordSpacing, '5px', "ctx.wordSpacing", "'5px'");
+
+ ctx.letterSpacing = '-1px';
+ ctx.wordSpacing = '-1px';
+ _assertSame(ctx.letterSpacing, '-1px', "ctx.letterSpacing", "'-1px'");
+ _assertSame(ctx.wordSpacing, '-1px', "ctx.wordSpacing", "'-1px'");
+
+ ctx.letterSpacing = '1PX';
+ ctx.wordSpacing = '10PX';
+ _assertSame(ctx.letterSpacing, '1px', "ctx.letterSpacing", "'1px'");
+ _assertSame(ctx.wordSpacing, '10px', "ctx.wordSpacing", "'10px'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.html
new file mode 100644
index 0000000000..a3f0f7133e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.font-relative.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.font-relative.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with font-relative length</p>
+
+
+<script>
+var t = async_test("Testing letter spacing and word spacing with font-relative length");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.letterSpacing = '1EX';
+ ctx.wordSpacing = '1EM';
+ _assertSame(ctx.letterSpacing, '1ex', "ctx.letterSpacing", "'1ex'");
+ _assertSame(ctx.wordSpacing, '1em', "ctx.wordSpacing", "'1em'");
+
+ ctx.letterSpacing = '1ch';
+ ctx.wordSpacing = '1ic';
+ _assertSame(ctx.letterSpacing, '1ch', "ctx.letterSpacing", "'1ch'");
+ _assertSame(ctx.wordSpacing, '1ic', "ctx.wordSpacing", "'1ic'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.worker.js
new file mode 100644
index 0000000000..cd653208e8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.font-relative.spacing.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.font-relative.spacing
+// Description:Testing letter spacing and word spacing with font-relative length
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing letter spacing and word spacing with font-relative length");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ ctx.letterSpacing = '1EX';
+ ctx.wordSpacing = '1EM';
+ _assertSame(ctx.letterSpacing, '1ex', "ctx.letterSpacing", "'1ex'");
+ _assertSame(ctx.wordSpacing, '1em', "ctx.wordSpacing", "'1em'");
+
+ ctx.letterSpacing = '1ch';
+ ctx.wordSpacing = '1ic';
+ _assertSame(ctx.letterSpacing, '1ch', "ctx.letterSpacing", "'1ch'");
+ _assertSame(ctx.wordSpacing, '1ic', "ctx.wordSpacing", "'1ic'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.html
new file mode 100644
index 0000000000..23f353513b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.fontKerning</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.fontKerning</h1>
+<p class="desc">Testing basic functionalities of fontKerning for canvas</p>
+
+
+<script>
+var t = async_test("Testing basic functionalities of fontKerning for canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "normal";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ width_normal = ctx.measureText("TAWATAVA").width;
+ ctx.fontKerning = "none";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ width_none = ctx.measureText("TAWATAVA").width;
+ _assert(width_normal < width_none, "width_normal < width_none");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.html
new file mode 100644
index 0000000000..7f6b57921e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.fontKerning.with.uppercase</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.fontKerning.with.uppercase</h1>
+<p class="desc">Testing basic functionalities of fontKerning for canvas</p>
+
+
+<script>
+var t = async_test("Testing basic functionalities of fontKerning for canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "Normal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "normal";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ ctx.fontKerning = "Auto";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "noRmal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NoRMal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NORMAL";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+
+ ctx.fontKerning = "None";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "none";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ ctx.fontKerning = "Auto";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nOne";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nonE";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NONE";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.worker.js
new file mode 100644
index 0000000000..4e0f32c692
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.with.uppercase.worker.js
@@ -0,0 +1,53 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.fontKerning.with.uppercase
+// Description:Testing basic functionalities of fontKerning for canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing basic functionalities of fontKerning for canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "Normal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "normal";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ ctx.fontKerning = "Auto";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "noRmal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NoRMal";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NORMAL";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+
+ ctx.fontKerning = "None";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "none";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ ctx.fontKerning = "Auto";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nOne";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nonE";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NONE";
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.worker.js
new file mode 100644
index 0000000000..ec64214c7f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontKerning.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.fontKerning
+// Description:Testing basic functionalities of fontKerning for canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing basic functionalities of fontKerning for canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.fontKerning, "auto", "ctx.fontKerning", "\"auto\"");
+ ctx.fontKerning = "normal";
+ _assertSame(ctx.fontKerning, "normal", "ctx.fontKerning", "\"normal\"");
+ width_normal = ctx.measureText("TAWATAVA").width;
+ ctx.fontKerning = "none";
+ _assertSame(ctx.fontKerning, "none", "ctx.fontKerning", "\"none\"");
+ width_none = ctx.measureText("TAWATAVA").width;
+ _assert(width_normal < width_none, "width_normal < width_none");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.html
new file mode 100644
index 0000000000..95405a18a5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.fontStretch.settings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.fontStretch.settings</h1>
+<p class="desc">Testing value setting of fontStretch in Canvas</p>
+
+
+<script>
+var t = async_test("Testing value setting of fontStretch in Canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Setting textRendering with lower cases
+ ctx.fontStretch = "ultra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-condensed", "ctx.fontStretch", "\"ultra-condensed\"");
+
+ ctx.fontStretch = "extra-condensed";
+ _assertSame(ctx.fontStretch, "extra-condensed", "ctx.fontStretch", "\"extra-condensed\"");
+
+ ctx.fontStretch = "condensed";
+ _assertSame(ctx.fontStretch, "condensed", "ctx.fontStretch", "\"condensed\"");
+
+ ctx.fontStretch = "semi-condensed";
+ _assertSame(ctx.fontStretch, "semi-condensed", "ctx.fontStretch", "\"semi-condensed\"");
+
+ ctx.fontStretch = "normal";
+ _assertSame(ctx.fontStretch, "normal", "ctx.fontStretch", "\"normal\"");
+
+ ctx.fontStretch = "semi-expanded";
+ _assertSame(ctx.fontStretch, "semi-expanded", "ctx.fontStretch", "\"semi-expanded\"");
+
+ ctx.fontStretch = "expanded";
+ _assertSame(ctx.fontStretch, "expanded", "ctx.fontStretch", "\"expanded\"");
+
+ ctx.fontStretch = "extra-expanded";
+ _assertSame(ctx.fontStretch, "extra-expanded", "ctx.fontStretch", "\"extra-expanded\"");
+
+ ctx.fontStretch = "ultra-expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ // Setting fontStretch with lower cases and upper cases word,
+ // these values should be ignored.
+ ctx.fontStretch = "ulTra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Extra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "cOndensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Semi-Condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "normaL";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "semi-Expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "eXtra-expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "abcd";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.worker.js
new file mode 100644
index 0000000000..ff10a742b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontStretch.settings.worker.js
@@ -0,0 +1,77 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.fontStretch.settings
+// Description:Testing value setting of fontStretch in Canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing value setting of fontStretch in Canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Setting textRendering with lower cases
+ ctx.fontStretch = "ultra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-condensed", "ctx.fontStretch", "\"ultra-condensed\"");
+
+ ctx.fontStretch = "extra-condensed";
+ _assertSame(ctx.fontStretch, "extra-condensed", "ctx.fontStretch", "\"extra-condensed\"");
+
+ ctx.fontStretch = "condensed";
+ _assertSame(ctx.fontStretch, "condensed", "ctx.fontStretch", "\"condensed\"");
+
+ ctx.fontStretch = "semi-condensed";
+ _assertSame(ctx.fontStretch, "semi-condensed", "ctx.fontStretch", "\"semi-condensed\"");
+
+ ctx.fontStretch = "normal";
+ _assertSame(ctx.fontStretch, "normal", "ctx.fontStretch", "\"normal\"");
+
+ ctx.fontStretch = "semi-expanded";
+ _assertSame(ctx.fontStretch, "semi-expanded", "ctx.fontStretch", "\"semi-expanded\"");
+
+ ctx.fontStretch = "expanded";
+ _assertSame(ctx.fontStretch, "expanded", "ctx.fontStretch", "\"expanded\"");
+
+ ctx.fontStretch = "extra-expanded";
+ _assertSame(ctx.fontStretch, "extra-expanded", "ctx.fontStretch", "\"extra-expanded\"");
+
+ ctx.fontStretch = "ultra-expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ // Setting fontStretch with lower cases and upper cases word,
+ // these values should be ignored.
+ ctx.fontStretch = "ulTra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Extra-condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "cOndensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Semi-Condensed";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "normaL";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "semi-Expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "Expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "eXtra-expanded";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+
+ ctx.fontStretch = "abcd";
+ _assertSame(ctx.fontStretch, "ultra-expanded", "ctx.fontStretch", "\"ultra-expanded\"");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.html
new file mode 100644
index 0000000000..9756d095ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.fontVariant.settings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.fontVariant.settings</h1>
+<p class="desc">Testing basic functionalities of fontVariant for canvas</p>
+
+
+<script>
+var t = async_test("Testing basic functionalities of fontVariant for canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Setting fontVariantCaps with lower cases
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "normal";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "small-caps";
+ _assertSame(ctx.fontVariantCaps, "small-caps", "ctx.fontVariantCaps", "\"small-caps\"");
+
+ ctx.fontVariantCaps = "all-small-caps";
+ _assertSame(ctx.fontVariantCaps, "all-small-caps", "ctx.fontVariantCaps", "\"all-small-caps\"");
+
+ ctx.fontVariantCaps = "petite-caps";
+ _assertSame(ctx.fontVariantCaps, "petite-caps", "ctx.fontVariantCaps", "\"petite-caps\"");
+
+ ctx.fontVariantCaps = "all-petite-caps";
+ _assertSame(ctx.fontVariantCaps, "all-petite-caps", "ctx.fontVariantCaps", "\"all-petite-caps\"");
+
+ ctx.fontVariantCaps = "unicase";
+ _assertSame(ctx.fontVariantCaps, "unicase", "ctx.fontVariantCaps", "\"unicase\"");
+
+ ctx.fontVariantCaps = "titling-caps";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+
+ // Setting fontVariantCaps with mixed-case values is not valid
+ ctx.fontVariantCaps = "nORmal";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+
+ ctx.fontVariantCaps = "normal";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "smaLL-caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "all-small-CAPS";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "pEtitE-caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "All-Petite-Caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "uNIcase";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "titling-CAPS";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ // Setting fontVariantCaps with non-existing font variant.
+ ctx.fontVariantCaps = "titling-caps";
+ ctx.fontVariantCaps = "abcd";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.worker.js
new file mode 100644
index 0000000000..30c78388ae
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.fontVariant.settings.worker.js
@@ -0,0 +1,74 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.fontVariant.settings
+// Description:Testing basic functionalities of fontVariant for canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing basic functionalities of fontVariant for canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Setting fontVariantCaps with lower cases
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "normal";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "small-caps";
+ _assertSame(ctx.fontVariantCaps, "small-caps", "ctx.fontVariantCaps", "\"small-caps\"");
+
+ ctx.fontVariantCaps = "all-small-caps";
+ _assertSame(ctx.fontVariantCaps, "all-small-caps", "ctx.fontVariantCaps", "\"all-small-caps\"");
+
+ ctx.fontVariantCaps = "petite-caps";
+ _assertSame(ctx.fontVariantCaps, "petite-caps", "ctx.fontVariantCaps", "\"petite-caps\"");
+
+ ctx.fontVariantCaps = "all-petite-caps";
+ _assertSame(ctx.fontVariantCaps, "all-petite-caps", "ctx.fontVariantCaps", "\"all-petite-caps\"");
+
+ ctx.fontVariantCaps = "unicase";
+ _assertSame(ctx.fontVariantCaps, "unicase", "ctx.fontVariantCaps", "\"unicase\"");
+
+ ctx.fontVariantCaps = "titling-caps";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+
+ // Setting fontVariantCaps with mixed-case values is not valid
+ ctx.fontVariantCaps = "nORmal";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+
+ ctx.fontVariantCaps = "normal";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "smaLL-caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "all-small-CAPS";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "pEtitE-caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "All-Petite-Caps";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "uNIcase";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ ctx.fontVariantCaps = "titling-CAPS";
+ _assertSame(ctx.fontVariantCaps, "normal", "ctx.fontVariantCaps", "\"normal\"");
+
+ // Setting fontVariantCaps with non-existing font variant.
+ ctx.fontVariantCaps = "titling-caps";
+ ctx.fontVariantCaps = "abcd";
+ _assertSame(ctx.fontVariantCaps, "titling-caps", "ctx.fontVariantCaps", "\"titling-caps\"");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.html
new file mode 100644
index 0000000000..d16b175ad6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.invalid.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.invalid.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with invalid units</p>
+
+
+<script>
+var t = async_test("Testing letter spacing and word spacing with invalid units");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ }
+ test_word_spacing('0s');
+ test_word_spacing('1min');
+ test_word_spacing('1deg');
+ test_word_spacing('1pp');
+ test_word_spacing('initial');
+ test_word_spacing('inherit');
+ test_word_spacing('normal');
+ test_word_spacing('none');
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.worker.js
new file mode 100644
index 0000000000..06207b2c6c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.invalid.spacing.worker.js
@@ -0,0 +1,38 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.invalid.spacing
+// Description:Testing letter spacing and word spacing with invalid units
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing letter spacing and word spacing with invalid units");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ }
+ test_word_spacing('0s');
+ test_word_spacing('1min');
+ test_word_spacing('1deg');
+ test_word_spacing('1pp');
+ test_word_spacing('initial');
+ test_word_spacing('inherit');
+ test_word_spacing('normal');
+ test_word_spacing('none');
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html
new file mode 100644
index 0000000000..f8b453418c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.letterSpacing.change.font</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.letterSpacing.change.font</h1>
+<p class="desc">Set letter spacing and word spacing to font dependent value and verify it works after font change.</p>
+
+
+<script>
+var t = async_test("Set letter spacing and word spacing to font dependent value and verify it works after font change.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ // Get the width for 'Hello World' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World').width;
+
+ ctx.letterSpacing = '1em';
+ _assertSame(ctx.letterSpacing, '1em', "ctx.letterSpacing", "'1em'");
+ // 1em = 10px. Add 10px after each letter in "Hello World",
+ // makes it 110px longer.
+ var width_with_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
+
+ // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
+ // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World').width;
+ // Now calculate the reference spacing for "Hello World" with no spacing.
+ ctx.letterSpacing = '0em';
+ width_normal = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js
new file mode 100644
index 0000000000..510845c885
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.letterSpacing.change.font
+// Description:Set letter spacing and word spacing to font dependent value and verify it works after font change.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Set letter spacing and word spacing to font dependent value and verify it works after font change.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ // Get the width for 'Hello World' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World').width;
+
+ ctx.letterSpacing = '1em';
+ _assertSame(ctx.letterSpacing, '1em', "ctx.letterSpacing", "'1em'");
+ // 1em = 10px. Add 10px after each letter in "Hello World",
+ // makes it 110px longer.
+ var width_with_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
+
+ // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
+ // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World').width;
+ // Now calculate the reference spacing for "Hello World" with no spacing.
+ ctx.letterSpacing = '0em';
+ width_normal = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.html
new file mode 100644
index 0000000000..a565770a16
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.letterSpacing.measure</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.letterSpacing.measure</h1>
+<p class="desc">Testing letter spacing with different length units</p>
+
+
+<script>
+var t = async_test("Testing letter spacing with different length units");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ var width_normal = ctx.measureText('Hello World').width;
+
+ function test_letter_spacing(value, difference_spacing, epsilon) {
+ ctx.letterSpacing = value;
+ _assertSame(ctx.letterSpacing, value, "ctx.letterSpacing", "value");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ width_with_letter_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_letter_spacing, width_normal + difference_spacing, epsilon, "letter spacing doesn't work.");
+ }
+
+ // The first value is the letter Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 11 letters
+ // in 'hello world', so the length difference is always letterSpacing * 11.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 33, 0.1],
+ ['5px', 55, 0.1],
+ ['-2px', -22, 0.1],
+ ['1em', 110, 0.1],
+ ['-0.1em', -11, 0.1],
+ ['1in', 1056, 0.1],
+ ['-0.1cm', -41.65, 0.2],
+ ['-0.6mm', -24,95, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_letter_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.worker.js
new file mode 100644
index 0000000000..630bf1d486
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.measure.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.letterSpacing.measure
+// Description:Testing letter spacing with different length units
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing letter spacing with different length units");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ var width_normal = ctx.measureText('Hello World').width;
+
+ function test_letter_spacing(value, difference_spacing, epsilon) {
+ ctx.letterSpacing = value;
+ _assertSame(ctx.letterSpacing, value, "ctx.letterSpacing", "value");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ width_with_letter_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_letter_spacing, width_normal + difference_spacing, epsilon, "letter spacing doesn't work.");
+ }
+
+ // The first value is the letter Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 11 letters
+ // in 'hello world', so the length difference is always letterSpacing * 11.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 33, 0.1],
+ ['5px', 55, 0.1],
+ ['-2px', -22, 0.1],
+ ['1em', 110, 0.1],
+ ['-0.1em', -11, 0.1],
+ ['1in', 1056, 0.1],
+ ['-0.1cm', -41.65, 0.2],
+ ['-0.6mm', -24,95, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_letter_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.html
new file mode 100644
index 0000000000..6c0b3756d3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.measure.direction</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.measure.direction</h1>
+<p class="desc">Measurement should follow text direction</p>
+
+
+<script>
+var t = async_test("Measurement should follow text direction");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.direction = "ltr";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+ ctx.direction = "rtl";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.worker.js
new file mode 100644
index 0000000000..852f372101
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.direction.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.measure.direction
+// Description:Measurement should follow text direction
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Measurement should follow text direction");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.direction = "ltr";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+ ctx.direction = "rtl";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.html
new file mode 100644
index 0000000000..335014cfd6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.measure.rtl.text</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.measure.rtl.text</h1>
+<p class="desc">Measurement should follow canvas direction instead text direction</p>
+
+
+<script>
+var t = async_test("Measurement should follow canvas direction instead text direction");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ metrics = ctx.measureText('اَلْعَرَبِيَّةُ');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.worker.js
new file mode 100644
index 0000000000..09b0e9b8d0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.rtl.text.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.measure.rtl.text
+// Description:Measurement should follow canvas direction instead text direction
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Measurement should follow canvas direction instead text direction");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ metrics = ctx.measureText('اَلْعَرَبِيَّةُ');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.html
new file mode 100644
index 0000000000..4c1ca193e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.measure.textAlign</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.measure.textAlign</h1>
+<p class="desc">Measurement should be related to textAlignment</p>
+
+
+<script>
+var t = async_test("Measurement should be related to textAlignment");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textAlign = "right";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight");
+
+ ctx.textAlign = "left"
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.worker.js
new file mode 100644
index 0000000000..bc6f167be5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.measure.textAlign.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.measure.textAlign
+// Description:Measurement should be related to textAlignment
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Measurement should be related to textAlignment");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.textAlign = "right";
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight");
+
+ ctx.textAlign = "left"
+ metrics = ctx.measureText('hello');
+ _assert(metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight, "metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.html
new file mode 100644
index 0000000000..48a592b839
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.nonfinite.spacing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.nonfinite.spacing</h1>
+<p class="desc">Testing letter spacing and word spacing with nonfinite inputs</p>
+
+
+<script>
+var t = async_test("Testing letter spacing and word spacing with nonfinite inputs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ }
+ test_word_spacing(NaN);
+ test_word_spacing(Infinity);
+ test_word_spacing(-Infinity);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.worker.js
new file mode 100644
index 0000000000..4cf20b28c0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.nonfinite.spacing.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.nonfinite.spacing
+// Description:Testing letter spacing and word spacing with nonfinite inputs
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing letter spacing and word spacing with nonfinite inputs");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ }
+ test_word_spacing(NaN);
+ test_word_spacing(Infinity);
+ test_word_spacing(-Infinity);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.html
new file mode 100644
index 0000000000..52b34deaab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.textRendering.settings</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.textRendering.settings</h1>
+<p class="desc">Testing basic functionalities of textRendering in Canvas</p>
+
+
+<script>
+var t = async_test("Testing basic functionalities of textRendering in Canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Setting textRendering with correct case.
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizeSpeed";
+ _assertSame(ctx.textRendering, "optimizeSpeed", "ctx.textRendering", "\"optimizeSpeed\"");
+
+ ctx.textRendering = "optimizeLegibility";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "geometricPrecision";
+ _assertSame(ctx.textRendering, "geometricPrecision", "ctx.textRendering", "\"geometricPrecision\"");
+
+ ctx.textRendering = "auto";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ // Setting textRendering with incorrect case is ignored.
+ ctx.textRendering = "OPtimizeSpeed";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "OPtimizELEgibility";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "GeometricPrecision";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizespeed";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizelegibility";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "geometricprecision";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizeLegibility";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "AUTO";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "Auto";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ // Setting textRendering with non-existing font variant.
+ ctx.textRendering = "abcd";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "normal";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "auto";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.worker.js
new file mode 100644
index 0000000000..a4381963f7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.textRendering.settings.worker.js
@@ -0,0 +1,76 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.textRendering.settings
+// Description:Testing basic functionalities of textRendering in Canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing basic functionalities of textRendering in Canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Setting textRendering with correct case.
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizeSpeed";
+ _assertSame(ctx.textRendering, "optimizeSpeed", "ctx.textRendering", "\"optimizeSpeed\"");
+
+ ctx.textRendering = "optimizeLegibility";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "geometricPrecision";
+ _assertSame(ctx.textRendering, "geometricPrecision", "ctx.textRendering", "\"geometricPrecision\"");
+
+ ctx.textRendering = "auto";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ // Setting textRendering with incorrect case is ignored.
+ ctx.textRendering = "OPtimizeSpeed";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "OPtimizELEgibility";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "GeometricPrecision";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizespeed";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizelegibility";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "geometricprecision";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+
+ ctx.textRendering = "optimizeLegibility";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "AUTO";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "Auto";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ // Setting textRendering with non-existing font variant.
+ ctx.textRendering = "abcd";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "normal";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "";
+ _assertSame(ctx.textRendering, "optimizeLegibility", "ctx.textRendering", "\"optimizeLegibility\"");
+
+ ctx.textRendering = "auto";
+ _assertSame(ctx.textRendering, "auto", "ctx.textRendering", "\"auto\"");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.html
new file mode 100644
index 0000000000..3df660ea3e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.wordSpacing.change.font</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.wordSpacing.change.font</h1>
+<p class="desc">Set word spacing and word spacing to font dependent value and verify it works after font change.</p>
+
+
+<script>
+var t = async_test("Set word spacing and word spacing to font dependent value and verify it works after font change.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ // Get the width for 'Hello World, again' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ ctx.wordSpacing = '1em';
+ _assertSame(ctx.wordSpacing, '1em', "ctx.wordSpacing", "'1em'");
+ // 1em = 10px. Add 10px after each word in "Hello World, again",
+ // makes it 20px longer.
+ var width_with_spacing = ctx.measureText('Hello World, again').width;
+ _assertSame(width_with_spacing, width_normal + 20, "width_with_spacing", "width_normal + 20");
+
+ // Changing font to 20px. Without resetting the spacing, 1em wordSpacing
+ // is now 20px, so it's suppose to be 40px longer without any wordSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World, again').width;
+ // Now calculate the reference spacing for "Hello World, again" with no spacing.
+ ctx.wordSpacing = '0em';
+ width_normal = ctx.measureText('Hello World, again').width;
+ _assertSame(width_with_spacing, width_normal + 40, "width_with_spacing", "width_normal + 40");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.worker.js
new file mode 100644
index 0000000000..e1415ea287
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.change.font.worker.js
@@ -0,0 +1,41 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.wordSpacing.change.font
+// Description:Set word spacing and word spacing to font dependent value and verify it works after font change.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Set word spacing and word spacing to font dependent value and verify it works after font change.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ // Get the width for 'Hello World, again' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ ctx.wordSpacing = '1em';
+ _assertSame(ctx.wordSpacing, '1em', "ctx.wordSpacing", "'1em'");
+ // 1em = 10px. Add 10px after each word in "Hello World, again",
+ // makes it 20px longer.
+ var width_with_spacing = ctx.measureText('Hello World, again').width;
+ _assertSame(width_with_spacing, width_normal + 20, "width_with_spacing", "width_normal + 20");
+
+ // Changing font to 20px. Without resetting the spacing, 1em wordSpacing
+ // is now 20px, so it's suppose to be 40px longer without any wordSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World, again').width;
+ // Now calculate the reference spacing for "Hello World, again" with no spacing.
+ ctx.wordSpacing = '0em';
+ width_normal = ctx.measureText('Hello World, again').width;
+ _assertSame(width_with_spacing, width_normal + 40, "width_with_spacing", "width_normal + 40");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.html
new file mode 100644
index 0000000000..7a1d867d0f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.drawing.style.wordSpacing.measure</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.drawing.style.wordSpacing.measure</h1>
+<p class="desc">Testing word spacing with different length units</p>
+
+
+<script>
+var t = async_test("Testing word spacing with different length units");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ function test_word_spacing(value, difference_spacing, epsilon) {
+ ctx.wordSpacing = value;
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, value, "ctx.wordSpacing", "value");
+ width_with_word_spacing = ctx.measureText('Hello World, again').width;
+ assert_approx_equals(width_with_word_spacing, width_normal + difference_spacing, epsilon, "word spacing doesn't work.");
+ }
+
+ // The first value is the word Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 2 words
+ // in 'Hello World, again', so the length difference is always wordSpacing * 2.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 6, 0.1],
+ ['5px', 10, 0.1],
+ ['-2px', -4, 0.1],
+ ['1em', 20, 0.1],
+ ['-0.5em', -10, 0.1],
+ ['1in', 192, 0.1],
+ ['-0.1cm', -7.57, 0.2],
+ ['-0.6mm', -4.54, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_word_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.worker.js
new file mode 100644
index 0000000000..b7acecb0eb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.drawing.style.wordSpacing.measure.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.drawing.style.wordSpacing.measure
+// Description:Testing word spacing with different length units
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing word spacing with different length units");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, '0px', "ctx.wordSpacing", "'0px'");
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ function test_word_spacing(value, difference_spacing, epsilon) {
+ ctx.wordSpacing = value;
+ _assertSame(ctx.letterSpacing, '0px', "ctx.letterSpacing", "'0px'");
+ _assertSame(ctx.wordSpacing, value, "ctx.wordSpacing", "value");
+ width_with_word_spacing = ctx.measureText('Hello World, again').width;
+ assert_approx_equals(width_with_word_spacing, width_normal + difference_spacing, epsilon, "word spacing doesn't work.");
+ }
+
+ // The first value is the word Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 2 words
+ // in 'Hello World, again', so the length difference is always wordSpacing * 2.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 6, 0.1],
+ ['5px', 10, 0.1],
+ ['-2px', -4, 0.1],
+ ['1em', 20, 0.1],
+ ['-0.5em', -10, 0.1],
+ ['1in', 192, 0.1],
+ ['-0.1cm', -7.57, 0.2],
+ ['-0.6mm', -4.54, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_word_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.html
new file mode 100644
index 0000000000..59828a5db4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.default</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.font, '10px sans-serif', "ctx.font", "'10px sans-serif'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.worker.js
new file mode 100644
index 0000000000..fa51ffc871
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.default.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.default
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ _assertSame(ctx.font, '10px sans-serif', "ctx.font", "'10px sans-serif'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.html
new file mode 100644
index 0000000000..bb39cc4a3c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.parse.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.parse.basic</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '20px serif';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20PX SERIF';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.worker.js
new file mode 100644
index 0000000000..3596aab66b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.basic.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.parse.basic
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '20px serif';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20PX SERIF';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.html
new file mode 100644
index 0000000000..69453437fe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.parse.complex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.parse.complex</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'small-caps italic 400 12px/2 Unknown Font, sans-serif';
+ _assert(['italic small-caps 12px "Unknown Font", sans-serif', 'italic small-caps 12px Unknown Font, sans-serif'].includes(ctx.font), "['italic small-caps 12px \"Unknown Font\", sans-serif', 'italic small-caps 12px Unknown Font, sans-serif'].includes(ctx.font)");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.worker.js
new file mode 100644
index 0000000000..71d039cfac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.parse.complex
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'small-caps italic 400 12px/2 Unknown Font, sans-serif';
+ _assert(['italic small-caps 12px "Unknown Font", sans-serif', 'italic small-caps 12px Unknown Font, sans-serif'].includes(ctx.font), "['italic small-caps 12px \"Unknown Font\", sans-serif', 'italic small-caps 12px Unknown Font, sans-serif'].includes(ctx.font)");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.html
new file mode 100644
index 0000000000..af94ac720a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.parse.complex2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.parse.complex2</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'small-caps italic 400 12px/2 "Unknown Font #2", sans-serif';
+ _assertSame(ctx.font, 'italic small-caps 12px "Unknown Font #2", sans-serif', "ctx.font", "'italic small-caps 12px \"Unknown Font #2\", sans-serif'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.worker.js
new file mode 100644
index 0000000000..45575f8814
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.complex2.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.parse.complex2
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'small-caps italic 400 12px/2 "Unknown Font #2", sans-serif';
+ _assertSame(ctx.font, 'italic small-caps 12px "Unknown Font #2", sans-serif', "ctx.font", "'italic small-caps 12px \"Unknown Font #2\", sans-serif'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.html
new file mode 100644
index 0000000000..989014fb37
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.parse.family</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.parse.family</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '20px cursive,fantasy,monospace,sans-serif,serif,UnquotedFont,"QuotedFont\\\\\\","';
+ _assertSame(ctx.font, '20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, "QuotedFont\\\\\\","', "ctx.font", "'20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, \"QuotedFont\\\\\\\\\\\\\",\"'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.worker.js
new file mode 100644
index 0000000000..68aefdd0df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.family.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.parse.family
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '20px cursive,fantasy,monospace,sans-serif,serif,UnquotedFont,"QuotedFont\\\\\\","';
+ _assertSame(ctx.font, '20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, "QuotedFont\\\\\\","', "ctx.font", "'20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, \"QuotedFont\\\\\\\\\\\\\",\"'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.html
new file mode 100644
index 0000000000..8b4fd01d02
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.parse.invalid</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.parse.invalid</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '20px serif';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'bogus';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'inherit';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px {bogus}';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px initial';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px default';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px inherit';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px revert';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x)';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x, 10px serif)';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '1em serif; background: green; margin: 10px';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.worker.js
new file mode 100644
index 0000000000..31f374579e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.invalid.worker.js
@@ -0,0 +1,67 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.parse.invalid
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '20px serif';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'bogus';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'inherit';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px {bogus}';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px initial';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px default';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px inherit';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '10px revert';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x)';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x, 10px serif)';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+
+ ctx.font = '20px serif';
+ ctx.font = '1em serif; background: green; margin: 10px';
+ _assertSame(ctx.font, '20px serif', "ctx.font", "'20px serif'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.html
new file mode 100644
index 0000000000..79ae6a38e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.parse.system</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.parse.system</h1>
+<p class="desc">System fonts must be computed to explicit values</p>
+
+
+<script>
+var t = async_test("System fonts must be computed to explicit values");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'message-box';
+ _assertDifferent(ctx.font, 'message-box', "ctx.font", "'message-box'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.worker.js
new file mode 100644
index 0000000000..b965ea763a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.system.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.parse.system
+// Description:System fonts must be computed to explicit values
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("System fonts must be computed to explicit values");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'message-box';
+ _assertDifferent(ctx.font, 'message-box', "ctx.font", "'message-box'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.html
new file mode 100644
index 0000000000..89f8515967
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.parse.tiny</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.parse.tiny</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '1px sans-serif';
+ _assertSame(ctx.font, '1px sans-serif', "ctx.font", "'1px sans-serif'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.worker.js
new file mode 100644
index 0000000000..aba023e336
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.parse.tiny.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.parse.tiny
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '1px sans-serif';
+ _assertSame(ctx.font, '1px sans-serif', "ctx.font", "'1px sans-serif'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.html
new file mode 100644
index 0000000000..a32be3d65c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.relative_size</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.relative_size</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '1em sans-serif';
+ _assertSame(ctx.font, '10px sans-serif', "ctx.font", "'10px sans-serif'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.worker.js
new file mode 100644
index 0000000000..9e1247cfe0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.relative_size.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.relative_size
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = '1em sans-serif';
+ _assertSame(ctx.font, '10px sans-serif', "ctx.font", "'10px sans-serif'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.html
new file mode 100644
index 0000000000..cac9c369b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.font.weight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.font.weight</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'italic 400 12px serif';
+ _assertSame(ctx.font, 'italic 12px serif', "ctx.font", "'italic 12px serif'");
+
+ ctx.font = 'italic 300 12px serif';
+ _assertSame(ctx.font, 'italic 300 12px serif', "ctx.font", "'italic 300 12px serif'");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.worker.js
new file mode 100644
index 0000000000..8f653c3656
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.font.weight.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.font.weight
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = 'italic 400 12px serif';
+ _assertSame(ctx.font, 'italic 12px serif', "ctx.font", "'italic 12px serif'");
+
+ ctx.font = 'italic 300 12px serif';
+ _assertSame(ctx.font, 'italic 300 12px serif', "ctx.font", "'italic 300 12px serif'");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html
new file mode 100644
index 0000000000..e2cef0d77a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps1</title>
+<h1>2d.text.fontVariantCaps1</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html
new file mode 100644
index 0000000000..3c216f07da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps1-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps1</title>
+<h1>2d.text.fontVariantCaps1</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "small-caps";
+ // This should render the same as font = "small-caps 32px serif".
+ ctx.fillText("Hello World", 20, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.w.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.w.html
new file mode 100644
index 0000000000..4bc1b36e17
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps1.w.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.text.fontVariantCaps1-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps1</title>
+<h1>2d.text.fontVariantCaps1</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "small-caps";
+ // This should render the same as font = "small-caps 32px serif".
+ ctx.fillText("Hello World", 20, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2-unexpected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2-unexpected.html
new file mode 100644
index 0000000000..dbcb8abd76
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2-unexpected.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML OffscreenCanvas reference</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+
+<canvas id="c1"></canvas>
+<br>
+<canvas id="c2"></canvas>
+
+<script>
+for (let c = 1; c <= 2; ++c) {
+ let ctx = document.getElementById("c" + c).getContext("2d");
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html
new file mode 100644
index 0000000000..e5bcff1831
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.fontVariantCaps2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.fontVariantCaps2</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+
+
+<script>
+var t = async_test("Testing small caps setting in fontVariant");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // "mismatch" test, to verify that small-caps does change the rendering.
+ smallCaps_len = ctx.measureText("Hello World").width;
+
+ ctx.font = "32px serif";
+ normalCaps_len = ctx.measureText("Hello World").width;
+ _assert(smallCaps_len != normalCaps_len, "smallCaps_len != normalCaps_len");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.js
new file mode 100644
index 0000000000..89f4f48c73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps2.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.fontVariantCaps2
+// Description:Testing small caps setting in fontVariant
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Testing small caps setting in fontVariant");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // "mismatch" test, to verify that small-caps does change the rendering.
+ smallCaps_len = ctx.measureText("Hello World").width;
+
+ ctx.font = "32px serif";
+ normalCaps_len = ctx.measureText("Hello World").width;
+ _assert(smallCaps_len != normalCaps_len, "smallCaps_len != normalCaps_len");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html
new file mode 100644
index 0000000000..cf2d5ae119
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps3</title>
+<h1>2d.text.fontVariantCaps3</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("hello world", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html
new file mode 100644
index 0000000000..48699a640f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps3-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps3</title>
+<h1>2d.text.fontVariantCaps3</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "all-small-caps";
+ // This should render the same as using font = "small-caps 32px serif"
+ // with all the underlying text in lowercase.
+ ctx.fillText("Hello World", 20, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.w.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.w.html
new file mode 100644
index 0000000000..cd5c1db818
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps3.w.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.text.fontVariantCaps3-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps3</title>
+<h1>2d.text.fontVariantCaps3</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "all-small-caps";
+ // This should render the same as using font = "small-caps 32px serif"
+ // with all the underlying text in lowercase.
+ ctx.fillText("Hello World", 20, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html
new file mode 100644
index 0000000000..3813fd3684
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps4</title>
+<h1>2d.text.fontVariantCaps4</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("hello world", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html
new file mode 100644
index 0000000000..b1b81b81e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps4-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps4</title>
+<h1>2d.text.fontVariantCaps4</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps overrides the small-caps setting from the font attribute
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.fillText("Hello World", 20, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.w.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.w.html
new file mode 100644
index 0000000000..0bae66fcd4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps4.w.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.text.fontVariantCaps4-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps4</title>
+<h1>2d.text.fontVariantCaps4</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps overrides the small-caps setting from the font attribute
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.fillText("Hello World", 20, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html
new file mode 100644
index 0000000000..4bda4ec4b5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps5</title>
+<h1>2d.text.fontVariantCaps5</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html
new file mode 100644
index 0000000000..2a6f7b5f73
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps5-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps5</title>
+<h1>2d.text.fontVariantCaps5</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps 'normal' does not override the setting from the font attribute.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "normal";
+ ctx.fillText("Hello World", 20, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.w.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.w.html
new file mode 100644
index 0000000000..8c59f5b517
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps5.w.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.text.fontVariantCaps5-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps5</title>
+<h1>2d.text.fontVariantCaps5</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps 'normal' does not override the setting from the font attribute.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "normal";
+ ctx.fillText("Hello World", 20, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html
new file mode 100644
index 0000000000..af9c736aea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.text.fontVariantCaps6</title>
+<h1>2d.text.fontVariantCaps6</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html
new file mode 100644
index 0000000000..c33684d388
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.text.fontVariantCaps6-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps6</title>
+<h1>2d.text.fontVariantCaps6</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ // fontVariantCaps is reset when the font attribute is set.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.w.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.w.html
new file mode 100644
index 0000000000..47f70d812b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.fontVariantCaps6.w.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.text.fontVariantCaps6-expected.html">
+<title>Canvas test: 2d.text.fontVariantCaps6</title>
+<h1>2d.text.fontVariantCaps6</h1>
+<p class="desc">Testing small caps setting in fontVariant</p>
+<canvas id="canvas" width="100" height="50">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(100, 50);
+ const ctx = canvas.getContext('2d');
+
+ // fontVariantCaps is reset when the font attribute is set.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.html
new file mode 100644
index 0000000000..105efc0794
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.actualBoundingBox</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.actualBoundingBox</h1>
+<p class="desc">Testing actualBoundingBox</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ ctx.baseline = 'alphabetic'
+ // Different platforms may render text slightly different.
+ // Values that are nominally expected to be zero might actually vary by a
+ // pixel or so if the UA accounts for antialiasing at glyph edges, so we
+ // allow a slight deviation.
+ _assert(Math.abs(ctx.measureText('A').actualBoundingBoxLeft) <= 1, "Math.abs(ctx.measureText('A').actualBoundingBoxLeft) <= 1");
+ _assert(ctx.measureText('A').actualBoundingBoxRight >= 50, "ctx.measureText('A').actualBoundingBoxRight >= 50");
+ _assert(ctx.measureText('A').actualBoundingBoxAscent >= 35, "ctx.measureText('A').actualBoundingBoxAscent >= 35");
+ _assert(Math.abs(ctx.measureText('A').actualBoundingBoxDescent) <= 1, "Math.abs(ctx.measureText('A').actualBoundingBoxDescent) <= 1");
+
+ _assert(ctx.measureText('D').actualBoundingBoxLeft >= 48, "ctx.measureText('D').actualBoundingBoxLeft >= 48");
+ _assert(ctx.measureText('D').actualBoundingBoxLeft <= 52, "ctx.measureText('D').actualBoundingBoxLeft <= 52");
+ _assert(ctx.measureText('D').actualBoundingBoxRight >= 75, "ctx.measureText('D').actualBoundingBoxRight >= 75");
+ _assert(ctx.measureText('D').actualBoundingBoxRight <= 80, "ctx.measureText('D').actualBoundingBoxRight <= 80");
+ _assert(ctx.measureText('D').actualBoundingBoxAscent >= 35, "ctx.measureText('D').actualBoundingBoxAscent >= 35");
+ _assert(ctx.measureText('D').actualBoundingBoxAscent <= 40, "ctx.measureText('D').actualBoundingBoxAscent <= 40");
+ _assert(ctx.measureText('D').actualBoundingBoxDescent >= 12, "ctx.measureText('D').actualBoundingBoxDescent >= 12");
+ _assert(ctx.measureText('D').actualBoundingBoxDescent <= 15, "ctx.measureText('D').actualBoundingBoxDescent <= 15");
+
+ _assert(Math.abs(ctx.measureText('ABCD').actualBoundingBoxLeft) <= 1, "Math.abs(ctx.measureText('ABCD').actualBoundingBoxLeft) <= 1");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxRight >= 200, "ctx.measureText('ABCD').actualBoundingBoxRight >= 200");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxAscent >= 85, "ctx.measureText('ABCD').actualBoundingBoxAscent >= 85");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxDescent >= 37, "ctx.measureText('ABCD').actualBoundingBoxDescent >= 37");
+
+}, "Testing actualBoundingBox");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.worker.js
new file mode 100644
index 0000000000..c3d18ff878
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.actualBoundingBox.worker.js
@@ -0,0 +1,46 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.actualBoundingBox
+// Description:Testing actualBoundingBox
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ ctx.baseline = 'alphabetic'
+ // Different platforms may render text slightly different.
+ // Values that are nominally expected to be zero might actually vary by a
+ // pixel or so if the UA accounts for antialiasing at glyph edges, so we
+ // allow a slight deviation.
+ _assert(Math.abs(ctx.measureText('A').actualBoundingBoxLeft) <= 1, "Math.abs(ctx.measureText('A').actualBoundingBoxLeft) <= 1");
+ _assert(ctx.measureText('A').actualBoundingBoxRight >= 50, "ctx.measureText('A').actualBoundingBoxRight >= 50");
+ _assert(ctx.measureText('A').actualBoundingBoxAscent >= 35, "ctx.measureText('A').actualBoundingBoxAscent >= 35");
+ _assert(Math.abs(ctx.measureText('A').actualBoundingBoxDescent) <= 1, "Math.abs(ctx.measureText('A').actualBoundingBoxDescent) <= 1");
+
+ _assert(ctx.measureText('D').actualBoundingBoxLeft >= 48, "ctx.measureText('D').actualBoundingBoxLeft >= 48");
+ _assert(ctx.measureText('D').actualBoundingBoxLeft <= 52, "ctx.measureText('D').actualBoundingBoxLeft <= 52");
+ _assert(ctx.measureText('D').actualBoundingBoxRight >= 75, "ctx.measureText('D').actualBoundingBoxRight >= 75");
+ _assert(ctx.measureText('D').actualBoundingBoxRight <= 80, "ctx.measureText('D').actualBoundingBoxRight <= 80");
+ _assert(ctx.measureText('D').actualBoundingBoxAscent >= 35, "ctx.measureText('D').actualBoundingBoxAscent >= 35");
+ _assert(ctx.measureText('D').actualBoundingBoxAscent <= 40, "ctx.measureText('D').actualBoundingBoxAscent <= 40");
+ _assert(ctx.measureText('D').actualBoundingBoxDescent >= 12, "ctx.measureText('D').actualBoundingBoxDescent >= 12");
+ _assert(ctx.measureText('D').actualBoundingBoxDescent <= 15, "ctx.measureText('D').actualBoundingBoxDescent <= 15");
+
+ _assert(Math.abs(ctx.measureText('ABCD').actualBoundingBoxLeft) <= 1, "Math.abs(ctx.measureText('ABCD').actualBoundingBoxLeft) <= 1");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxRight >= 200, "ctx.measureText('ABCD').actualBoundingBoxRight >= 200");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxAscent >= 85, "ctx.measureText('ABCD').actualBoundingBoxAscent >= 85");
+ _assert(ctx.measureText('ABCD').actualBoundingBoxDescent >= 37, "ctx.measureText('ABCD').actualBoundingBoxDescent >= 37");
+ t.done();
+}, "Testing actualBoundingBox");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.html
new file mode 100644
index 0000000000..2eec005cb8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.advances</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.advances</h1>
+<p class="desc">Testing width advances</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ // Some platforms may return '-0'.
+ _assertSame(Math.abs(ctx.measureText('Hello').advances[0]), 0, "Math.abs(ctx.measureText('Hello').advances[\""+(0)+"\"])", "0");
+ // Different platforms may render text slightly different.
+ _assert(ctx.measureText('Hello').advances[1] >= 36, "ctx.measureText('Hello').advances[\""+(1)+"\"] >= 36");
+ _assert(ctx.measureText('Hello').advances[2] >= 58, "ctx.measureText('Hello').advances[\""+(2)+"\"] >= 58");
+ _assert(ctx.measureText('Hello').advances[3] >= 70, "ctx.measureText('Hello').advances[\""+(3)+"\"] >= 70");
+ _assert(ctx.measureText('Hello').advances[4] >= 80, "ctx.measureText('Hello').advances[\""+(4)+"\"] >= 80");
+
+ var tm = ctx.measureText('Hello');
+ _assertSame(ctx.measureText('Hello').advances[0], tm.advances[0], "ctx.measureText('Hello').advances[\""+(0)+"\"]", "tm.advances[\""+(0)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[1], tm.advances[1], "ctx.measureText('Hello').advances[\""+(1)+"\"]", "tm.advances[\""+(1)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[2], tm.advances[2], "ctx.measureText('Hello').advances[\""+(2)+"\"]", "tm.advances[\""+(2)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[3], tm.advances[3], "ctx.measureText('Hello').advances[\""+(3)+"\"]", "tm.advances[\""+(3)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[4], tm.advances[4], "ctx.measureText('Hello').advances[\""+(4)+"\"]", "tm.advances[\""+(4)+"\"]");
+
+}, "Testing width advances");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.worker.js
new file mode 100644
index 0000000000..4b02f06f2d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.advances.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.advances
+// Description:Testing width advances
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ // Some platforms may return '-0'.
+ _assertSame(Math.abs(ctx.measureText('Hello').advances[0]), 0, "Math.abs(ctx.measureText('Hello').advances[\""+(0)+"\"])", "0");
+ // Different platforms may render text slightly different.
+ _assert(ctx.measureText('Hello').advances[1] >= 36, "ctx.measureText('Hello').advances[\""+(1)+"\"] >= 36");
+ _assert(ctx.measureText('Hello').advances[2] >= 58, "ctx.measureText('Hello').advances[\""+(2)+"\"] >= 58");
+ _assert(ctx.measureText('Hello').advances[3] >= 70, "ctx.measureText('Hello').advances[\""+(3)+"\"] >= 70");
+ _assert(ctx.measureText('Hello').advances[4] >= 80, "ctx.measureText('Hello').advances[\""+(4)+"\"] >= 80");
+
+ var tm = ctx.measureText('Hello');
+ _assertSame(ctx.measureText('Hello').advances[0], tm.advances[0], "ctx.measureText('Hello').advances[\""+(0)+"\"]", "tm.advances[\""+(0)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[1], tm.advances[1], "ctx.measureText('Hello').advances[\""+(1)+"\"]", "tm.advances[\""+(1)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[2], tm.advances[2], "ctx.measureText('Hello').advances[\""+(2)+"\"]", "tm.advances[\""+(2)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[3], tm.advances[3], "ctx.measureText('Hello').advances[\""+(3)+"\"]", "tm.advances[\""+(3)+"\"]");
+ _assertSame(ctx.measureText('Hello').advances[4], tm.advances[4], "ctx.measureText('Hello').advances[\""+(4)+"\"]", "tm.advances[\""+(4)+"\"]");
+ t.done();
+}, "Testing width advances");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.html
new file mode 100644
index 0000000000..9d0cc1268d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.baselines</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.baselines</h1>
+<p class="desc">Testing baselines</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(Math.abs(ctx.measureText('A').alphabeticBaseline), 0, "Math.abs(ctx.measureText('A').alphabeticBaseline)", "0");
+ _assertSame(ctx.measureText('A').ideographicBaseline, 6.25, "ctx.measureText('A').ideographicBaseline", "6.25");
+ _assertSame(ctx.measureText('A').hangingBaseline, 25, "ctx.measureText('A').hangingBaseline", "25");
+
+ _assertSame(Math.abs(ctx.measureText('ABCD').alphabeticBaseline), 0, "Math.abs(ctx.measureText('ABCD').alphabeticBaseline)", "0");
+ _assertSame(ctx.measureText('ABCD').ideographicBaseline, 6.25, "ctx.measureText('ABCD').ideographicBaseline", "6.25");
+ _assertSame(ctx.measureText('ABCD').hangingBaseline, 25, "ctx.measureText('ABCD').hangingBaseline", "25");
+
+}, "Testing baselines");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.worker.js
new file mode 100644
index 0000000000..ddb48f4fe0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.baselines.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.baselines
+// Description:Testing baselines
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(Math.abs(ctx.measureText('A').alphabeticBaseline), 0, "Math.abs(ctx.measureText('A').alphabeticBaseline)", "0");
+ _assertSame(ctx.measureText('A').ideographicBaseline, 6.25, "ctx.measureText('A').ideographicBaseline", "6.25");
+ _assertSame(ctx.measureText('A').hangingBaseline, 25, "ctx.measureText('A').hangingBaseline", "25");
+
+ _assertSame(Math.abs(ctx.measureText('ABCD').alphabeticBaseline), 0, "Math.abs(ctx.measureText('ABCD').alphabeticBaseline)", "0");
+ _assertSame(ctx.measureText('ABCD').ideographicBaseline, 6.25, "ctx.measureText('ABCD').ideographicBaseline", "6.25");
+ _assertSame(ctx.measureText('ABCD').hangingBaseline, 25, "ctx.measureText('ABCD').hangingBaseline", "25");
+ t.done();
+}, "Testing baselines");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.html
new file mode 100644
index 0000000000..2e2e5dde67
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.emHeights-low-ascent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.emHeights-low-ascent</h1>
+<p class="desc">Testing emHeights with reduced ascent metric</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-ascent256", "url('/fonts/CanvasTest-ascent256.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 20, "ctx.measureText('A').emHeightAscent", "20");
+ _assertSame(ctx.measureText('A').emHeightDescent, 20, "ctx.measureText('A').emHeightDescent", "20");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 20, "ctx.measureText('ABCD').emHeightAscent", "20");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 20, "ctx.measureText('ABCD').emHeightDescent", "20");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+
+}, "Testing emHeights with reduced ascent metric");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.worker.js
new file mode 100644
index 0000000000..09ee787309
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-low-ascent.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.emHeights-low-ascent
+// Description:Testing emHeights with reduced ascent metric
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-ascent256", "url('/fonts/CanvasTest-ascent256.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 20, "ctx.measureText('A').emHeightAscent", "20");
+ _assertSame(ctx.measureText('A').emHeightDescent, 20, "ctx.measureText('A').emHeightDescent", "20");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 20, "ctx.measureText('ABCD').emHeightAscent", "20");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 20, "ctx.measureText('ABCD').emHeightDescent", "20");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+ t.done();
+}, "Testing emHeights with reduced ascent metric");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.html
new file mode 100644
index 0000000000..e39c08ce82
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.emHeights-zero-descent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.emHeights-zero-descent</h1>
+<p class="desc">Testing emHeights with zero descent metric</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-descent0", "url('/fonts/CanvasTest-descent0.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightAscent", "40");
+ _assertSame(ctx.measureText('A').emHeightDescent, 0, "ctx.measureText('A').emHeightDescent", "0");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightAscent", "40");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 0, "ctx.measureText('ABCD').emHeightDescent", "0");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+
+}, "Testing emHeights with zero descent metric");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.worker.js
new file mode 100644
index 0000000000..a2f09782c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights-zero-descent.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.emHeights-zero-descent
+// Description:Testing emHeights with zero descent metric
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-descent0", "url('/fonts/CanvasTest-descent0.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightAscent", "40");
+ _assertSame(ctx.measureText('A').emHeightDescent, 0, "ctx.measureText('A').emHeightDescent", "0");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightAscent", "40");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 0, "ctx.measureText('ABCD').emHeightDescent", "0");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+ t.done();
+}, "Testing emHeights with zero descent metric");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.html
new file mode 100644
index 0000000000..0764279df3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.emHeights</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.emHeights</h1>
+<p class="desc">Testing emHeights</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 30, "ctx.measureText('A').emHeightAscent", "30");
+ _assertSame(ctx.measureText('A').emHeightDescent, 10, "ctx.measureText('A').emHeightDescent", "10");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 30, "ctx.measureText('ABCD').emHeightAscent", "30");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 10, "ctx.measureText('ABCD').emHeightDescent", "10");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+
+}, "Testing emHeights");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.worker.js
new file mode 100644
index 0000000000..0385d3d737
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.emHeights.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.emHeights
+// Description:Testing emHeights
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').emHeightAscent, 30, "ctx.measureText('A').emHeightAscent", "30");
+ _assertSame(ctx.measureText('A').emHeightDescent, 10, "ctx.measureText('A').emHeightDescent", "10");
+ _assertSame(ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent, 40, "ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent", "40");
+
+ _assertSame(ctx.measureText('ABCD').emHeightAscent, 30, "ctx.measureText('ABCD').emHeightAscent", "30");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent, 10, "ctx.measureText('ABCD').emHeightDescent", "10");
+ _assertSame(ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent, 40, "ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent", "40");
+ t.done();
+}, "Testing emHeights");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.html
new file mode 100644
index 0000000000..51eb2c822c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.fontBoundingBox-reduced-ascent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.fontBoundingBox-reduced-ascent</h1>
+<p class="desc">Testing fontBoundingBox for OffscreenCanvas with reduced ascent metric</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-ascent256", "url('/fonts/CanvasTest-ascent256.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 10, "ctx.measureText('A').fontBoundingBoxAscent", "10");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 10, "ctx.measureText('ABCD').fontBoundingBoxAscent", "10");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+
+}, "Testing fontBoundingBox for OffscreenCanvas with reduced ascent metric");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.worker.js
new file mode 100644
index 0000000000..dea67ff8f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-reduced-ascent.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.fontBoundingBox-reduced-ascent
+// Description:Testing fontBoundingBox for OffscreenCanvas with reduced ascent metric
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-ascent256", "url('/fonts/CanvasTest-ascent256.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 10, "ctx.measureText('A').fontBoundingBoxAscent", "10");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 10, "ctx.measureText('ABCD').fontBoundingBoxAscent", "10");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+ t.done();
+}, "Testing fontBoundingBox for OffscreenCanvas with reduced ascent metric");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.html
new file mode 100644
index 0000000000..ea65e58b5c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.fontBoundingBox-zero-descent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.fontBoundingBox-zero-descent</h1>
+<p class="desc">Testing fontBoundingBox for OffscreenCanvas with zero descent metric</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-descent0", "url('/fonts/CanvasTest-descent0.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 30, "ctx.measureText('A').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 0, "ctx.measureText('A').fontBoundingBoxDescent", "0");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 30, "ctx.measureText('ABCD').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 0, "ctx.measureText('ABCD').fontBoundingBoxDescent", "0");
+
+}, "Testing fontBoundingBox for OffscreenCanvas with zero descent metric");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.worker.js
new file mode 100644
index 0000000000..99a886d015
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox-zero-descent.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.fontBoundingBox-zero-descent
+// Description:Testing fontBoundingBox for OffscreenCanvas with zero descent metric
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest-descent0", "url('/fonts/CanvasTest-descent0.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 30, "ctx.measureText('A').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 0, "ctx.measureText('A').fontBoundingBoxDescent", "0");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 30, "ctx.measureText('ABCD').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 0, "ctx.measureText('ABCD').fontBoundingBoxDescent", "0");
+ t.done();
+}, "Testing fontBoundingBox for OffscreenCanvas with zero descent metric");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.html
new file mode 100644
index 0000000000..cb8b0c558d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.fontBoundingBox.ahem</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.fontBoundingBox.ahem</h1>
+<p class="desc">Testing fontBoundingBox for font ahem</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("Ahem", "url('/fonts/Ahem.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px Ahem';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 40, "ctx.measureText('A').fontBoundingBoxAscent", "40");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 40, "ctx.measureText('ABCD').fontBoundingBoxAscent", "40");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+
+}, "Testing fontBoundingBox for font ahem");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.worker.js
new file mode 100644
index 0000000000..255bcd108a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.ahem.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.fontBoundingBox.ahem
+// Description:Testing fontBoundingBox for font ahem
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("Ahem", "url('/fonts/Ahem.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px Ahem';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 40, "ctx.measureText('A').fontBoundingBoxAscent", "40");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 40, "ctx.measureText('ABCD').fontBoundingBoxAscent", "40");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+ t.done();
+}, "Testing fontBoundingBox for font ahem");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.html
new file mode 100644
index 0000000000..36b11f31d7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.fontBoundingBox</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.fontBoundingBox</h1>
+<p class="desc">Testing fontBoundingBox measurements</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 30, "ctx.measureText('A').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 30, "ctx.measureText('ABCD').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+
+}, "Testing fontBoundingBox measurements");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.worker.js
new file mode 100644
index 0000000000..b2cde04c0d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.fontBoundingBox.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.fontBoundingBox
+// Description:Testing fontBoundingBox measurements
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ _assertSame(ctx.measureText('A').fontBoundingBoxAscent, 30, "ctx.measureText('A').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('A').fontBoundingBoxDescent, 10, "ctx.measureText('A').fontBoundingBoxDescent", "10");
+
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxAscent, 30, "ctx.measureText('ABCD').fontBoundingBoxAscent", "30");
+ _assertSame(ctx.measureText('ABCD').fontBoundingBoxDescent, 10, "ctx.measureText('ABCD').fontBoundingBoxDescent", "10");
+ t.done();
+}, "Testing fontBoundingBox measurements");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.html
new file mode 100644
index 0000000000..fea1904083
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.width.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.width.basic</h1>
+<p class="desc">The width of character is same as font used</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText('A').width, 50, "ctx.measureText('A').width", "50");
+ _assertSame(ctx.measureText('AA').width, 100, "ctx.measureText('AA').width", "100");
+ _assertSame(ctx.measureText('ABCD').width, 200, "ctx.measureText('ABCD').width", "200");
+
+ ctx.font = '100px CanvasTest';
+ _assertSame(ctx.measureText('A').width, 100, "ctx.measureText('A').width", "100");
+
+}, "The width of character is same as font used");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.worker.js
new file mode 100644
index 0000000000..866ad8b3c5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.basic.worker.js
@@ -0,0 +1,27 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.width.basic
+// Description:The width of character is same as font used
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText('A').width, 50, "ctx.measureText('A').width", "50");
+ _assertSame(ctx.measureText('AA').width, 100, "ctx.measureText('AA').width", "100");
+ _assertSame(ctx.measureText('ABCD').width, 200, "ctx.measureText('ABCD').width", "200");
+
+ ctx.font = '100px CanvasTest';
+ _assertSame(ctx.measureText('A').width, 100, "ctx.measureText('A').width", "100");
+ t.done();
+}, "The width of character is same as font used");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.html
new file mode 100644
index 0000000000..11bd029433
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.width.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.width.empty</h1>
+<p class="desc">The empty string has zero width</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText("").width, 0, "ctx.measureText(\"\").width", "0");
+
+}, "The empty string has zero width");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.worker.js
new file mode 100644
index 0000000000..6fb89c5ba7
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.empty.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.width.empty
+// Description:The empty string has zero width
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText("").width, 0, "ctx.measureText(\"\").width", "0");
+ t.done();
+}, "The empty string has zero width");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.html
new file mode 100644
index 0000000000..38d5084298
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.measure.width.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.measure.width.space</h1>
+<p class="desc">Space characters are converted to U+0020 and NOT collapsed</p>
+
+
+<script>
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ document.fonts.add(f);
+ await document.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText('A B').width, 150, "ctx.measureText('A B').width", "150");
+ _assertSame(ctx.measureText('A B').width, 200, "ctx.measureText('A B').width", "200");
+ _assertSame(ctx.measureText('A \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dB').width, 650, "ctx.measureText('A \\x09\\x0a\\x0c\\x0d \\x09\\x0a\\x0c\\x0dB').width", "650");
+ _assert(ctx.measureText('A \x0b B').width >= 200, "ctx.measureText('A \\x0b B').width >= 200");
+
+ _assertSame(ctx.measureText(' AB').width, 150, "ctx.measureText(' AB').width", "150");
+ _assertSame(ctx.measureText('AB ').width, 150, "ctx.measureText('AB ').width", "150");
+
+}, "Space characters are converted to U+0020 and NOT collapsed");
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.worker.js
new file mode 100644
index 0000000000..d832feec5f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.measure.width.space.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.measure.width.space
+// Description:Space characters are converted to U+0020 and NOT collapsed
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+promise_test(async t => {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
+ f.load();
+ self.fonts.add(f);
+ await self.fonts.ready;
+ ctx.font = '50px CanvasTest';
+ _assertSame(ctx.measureText('A B').width, 150, "ctx.measureText('A B').width", "150");
+ _assertSame(ctx.measureText('A B').width, 200, "ctx.measureText('A B').width", "200");
+ _assertSame(ctx.measureText('A \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dB').width, 650, "ctx.measureText('A \\x09\\x0a\\x0c\\x0d \\x09\\x0a\\x0c\\x0dB').width", "650");
+ _assert(ctx.measureText('A \x0b B').width >= 200, "ctx.measureText('A \\x0b B').width >= 200");
+
+ _assertSame(ctx.measureText(' AB').width, 150, "ctx.measureText(' AB').width", "150");
+ _assertSame(ctx.measureText('AB ').width, 150, "ctx.measureText('AB ').width", "150");
+ t.done();
+}, "Space characters are converted to U+0020 and NOT collapsed");
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.html b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.html
new file mode 100644
index 0000000000..89d8fe3c7a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.text.setFont.mathFont</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.text.setFont.mathFont</h1>
+<p class="desc">crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font</p>
+
+
+<script>
+var t = async_test("crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = "math serif";
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.worker.js b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.worker.js
new file mode 100644
index 0000000000..b756b45dc5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/2d.text.setFont.mathFont.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.text.setFont.mathFont
+// Description:crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.font = "math serif";
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch-ref.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch-ref.html
new file mode 100644
index 0000000000..00ecdccad3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext('2d');
+
+function draw() {
+ ctx.font = '25px test';
+ ctx.fillText("P", 10, 40);
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+document.fonts.add(f);
+
+f.load().then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.condensed.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.condensed.html
new file mode 100644
index 0000000000..0cbd5e3c1f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.condensed.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "condensed";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.expanded.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.expanded.html
new file mode 100644
index 0000000000..5ec853985f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.expanded.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "expanded";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-condensed.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-condensed.html
new file mode 100644
index 0000000000..12843c53b8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-condensed.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = extra-condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "extra-condensed";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "extra-condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-expanded.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-expanded.html
new file mode 100644
index 0000000000..20d801718a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.extra-expanded.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = extra-expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "extra-expanded";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "extra-expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.normal.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.normal.html
new file mode 100644
index 0000000000..786cb408e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.normal.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = normal and shows as fail for
+// fontStretch = expanded or condensed.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/fail.woff)');
+f.stretch = "expanded";
+document.fonts.add(f);
+
+var f1 = new FontFace('test', 'url(/fonts/pass.woff)');
+document.fonts.add(f1);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+f2.stretch = "condensed";
+document.fonts.add(f2);
+
+Promise.all([f.load(), f1.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-condensed.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-condensed.html
new file mode 100644
index 0000000000..04bd5a80d0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-condensed.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = semi-condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "semi-condensed";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "semi-condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-expanded.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-expanded.html
new file mode 100644
index 0000000000..d86b730687
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.semi-expanded.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = semi-expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "semi-expanded";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "semi-expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-condensed.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-condensed.html
new file mode 100644
index 0000000000..d78f6d0078
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-condensed.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = ultra-condensed and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "ultra-condensed";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "ultra-condensed";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-expanded.html b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-expanded.html
new file mode 100644
index 0000000000..8b8f6f5698
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/text/canvas.2d.fontStretch.ultra-expanded.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Canvas test: 2d.text.fontStretch</title>
+<link rel="match" href="canvas.2d.fontStretch-ref.html">
+<canvas id="c" class="output"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+
+var canvas = new OffscreenCanvas(300, 150);
+var ctx = canvas.getContext('2d');
+
+// P shows as Pass for fontStretch = ultra-expanded and shows as fail for
+// fontStretch = fail.
+function draw() {
+ ctx.font = '25px test';
+ ctx.fontStretch = "ultra-expanded";
+ ctx.fillText("P", 10, 40);
+ document.getElementById('c')
+ .getContext("bitmaprenderer")
+ .transferFromImageBitmap(canvas.transferToImageBitmap());
+}
+
+var f = new FontFace('test', 'url(/fonts/pass.woff)');
+f.stretch = "ultra-expanded";
+document.fonts.add(f);
+
+var f2 = new FontFace('test', 'url(/fonts/fail.woff)');
+document.fonts.add(f2);
+
+Promise.all([f.load(), f2.load()]).then(draw);
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.html
new file mode 100644
index 0000000000..208043fbf6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.bitmap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.bitmap</h1>
+<p class="desc">save()/restore() does not affect the current bitmap</p>
+
+
+<script>
+var t = async_test("save()/restore() does not affect the current bitmap");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.worker.js
new file mode 100644
index 0000000000..09c7dcca90
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.bitmap.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.bitmap
+// Description:save()/restore() does not affect the current bitmap
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() does not affect the current bitmap");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.html
new file mode 100644
index 0000000000..f4d6b6f6e1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.clip</h1>
+<p class="desc">save()/restore() affects the clipping path</p>
+
+
+<script>
+var t = async_test("save()/restore() affects the clipping path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.worker.js
new file mode 100644
index 0000000000..a7bc0615e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.clip.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.clip
+// Description:save()/restore() affects the clipping path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() affects the clipping path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.html
new file mode 100644
index 0000000000..789e1e8d2b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.fillStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.fillStyle</h1>
+<p class="desc">save()/restore() works for fillStyle</p>
+
+
+<script>
+var t = async_test("save()/restore() works for fillStyle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.fillStyle;
+ ctx.save();
+ ctx.fillStyle = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.fillStyle, old, "ctx.fillStyle", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.fillStyle = "#ff0000";
+ old = ctx.fillStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.fillStyle, old, "ctx.fillStyle", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.worker.js
new file mode 100644
index 0000000000..46cf6d1daa
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.fillStyle.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.fillStyle
+// Description:save()/restore() works for fillStyle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for fillStyle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.fillStyle;
+ ctx.save();
+ ctx.fillStyle = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.fillStyle, old, "ctx.fillStyle", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.fillStyle = "#ff0000";
+ old = ctx.fillStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.fillStyle, old, "ctx.fillStyle", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.html
new file mode 100644
index 0000000000..15b59725ab
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.globalAlpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.globalAlpha</h1>
+<p class="desc">save()/restore() works for globalAlpha</p>
+
+
+<script>
+var t = async_test("save()/restore() works for globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalAlpha;
+ ctx.save();
+ ctx.globalAlpha = 0.5;
+ ctx.restore();
+ _assertSame(ctx.globalAlpha, old, "ctx.globalAlpha", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.globalAlpha = 0.5;
+ old = ctx.globalAlpha;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.globalAlpha, old, "ctx.globalAlpha", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.worker.js
new file mode 100644
index 0000000000..765f8b00a3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalAlpha.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.globalAlpha
+// Description:save()/restore() works for globalAlpha
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for globalAlpha");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalAlpha;
+ ctx.save();
+ ctx.globalAlpha = 0.5;
+ ctx.restore();
+ _assertSame(ctx.globalAlpha, old, "ctx.globalAlpha", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.globalAlpha = 0.5;
+ old = ctx.globalAlpha;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.globalAlpha, old, "ctx.globalAlpha", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html
new file mode 100644
index 0000000000..1efb24aa9b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.globalCompositeOperation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.globalCompositeOperation</h1>
+<p class="desc">save()/restore() works for globalCompositeOperation</p>
+
+
+<script>
+var t = async_test("save()/restore() works for globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalCompositeOperation;
+ ctx.save();
+ ctx.globalCompositeOperation = "copy";
+ ctx.restore();
+ _assertSame(ctx.globalCompositeOperation, old, "ctx.globalCompositeOperation", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.globalCompositeOperation = "copy";
+ old = ctx.globalCompositeOperation;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "copy"
+ ctx.save();
+ _assertSame(ctx.globalCompositeOperation, old, "ctx.globalCompositeOperation", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.worker.js
new file mode 100644
index 0000000000..cd38d56c51
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.globalCompositeOperation.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.globalCompositeOperation
+// Description:save()/restore() works for globalCompositeOperation
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for globalCompositeOperation");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalCompositeOperation;
+ ctx.save();
+ ctx.globalCompositeOperation = "copy";
+ ctx.restore();
+ _assertSame(ctx.globalCompositeOperation, old, "ctx.globalCompositeOperation", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.globalCompositeOperation = "copy";
+ old = ctx.globalCompositeOperation;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "copy"
+ ctx.save();
+ _assertSame(ctx.globalCompositeOperation, old, "ctx.globalCompositeOperation", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.html
new file mode 100644
index 0000000000..5e651d0c7b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.lineCap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.lineCap</h1>
+<p class="desc">save()/restore() works for lineCap</p>
+
+
+<script>
+var t = async_test("save()/restore() works for lineCap");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineCap;
+ ctx.save();
+ ctx.lineCap = "round";
+ ctx.restore();
+ _assertSame(ctx.lineCap, old, "ctx.lineCap", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineCap = "round";
+ old = ctx.lineCap;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ _assertSame(ctx.lineCap, old, "ctx.lineCap", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.worker.js
new file mode 100644
index 0000000000..9895b44b00
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineCap.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.lineCap
+// Description:save()/restore() works for lineCap
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for lineCap");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineCap;
+ ctx.save();
+ ctx.lineCap = "round";
+ ctx.restore();
+ _assertSame(ctx.lineCap, old, "ctx.lineCap", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineCap = "round";
+ old = ctx.lineCap;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ _assertSame(ctx.lineCap, old, "ctx.lineCap", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.html
new file mode 100644
index 0000000000..20f53fec50
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.lineJoin</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.lineJoin</h1>
+<p class="desc">save()/restore() works for lineJoin</p>
+
+
+<script>
+var t = async_test("save()/restore() works for lineJoin");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineJoin;
+ ctx.save();
+ ctx.lineJoin = "round";
+ ctx.restore();
+ _assertSame(ctx.lineJoin, old, "ctx.lineJoin", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineJoin = "round";
+ old = ctx.lineJoin;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ _assertSame(ctx.lineJoin, old, "ctx.lineJoin", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.worker.js
new file mode 100644
index 0000000000..e8c85825f1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineJoin.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.lineJoin
+// Description:save()/restore() works for lineJoin
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for lineJoin");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineJoin;
+ ctx.save();
+ ctx.lineJoin = "round";
+ ctx.restore();
+ _assertSame(ctx.lineJoin, old, "ctx.lineJoin", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineJoin = "round";
+ old = ctx.lineJoin;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ _assertSame(ctx.lineJoin, old, "ctx.lineJoin", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.html
new file mode 100644
index 0000000000..e234e3efc2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.lineWidth</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.lineWidth</h1>
+<p class="desc">save()/restore() works for lineWidth</p>
+
+
+<script>
+var t = async_test("save()/restore() works for lineWidth");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineWidth;
+ ctx.save();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ _assertSame(ctx.lineWidth, old, "ctx.lineWidth", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineWidth = 0.5;
+ old = ctx.lineWidth;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.lineWidth, old, "ctx.lineWidth", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.worker.js
new file mode 100644
index 0000000000..997748c377
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.lineWidth.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.lineWidth
+// Description:save()/restore() works for lineWidth
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for lineWidth");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineWidth;
+ ctx.save();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ _assertSame(ctx.lineWidth, old, "ctx.lineWidth", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineWidth = 0.5;
+ old = ctx.lineWidth;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.lineWidth, old, "ctx.lineWidth", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.html
new file mode 100644
index 0000000000..1df2b2420f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.miterLimit</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.miterLimit</h1>
+<p class="desc">save()/restore() works for miterLimit</p>
+
+
+<script>
+var t = async_test("save()/restore() works for miterLimit");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.miterLimit;
+ ctx.save();
+ ctx.miterLimit = 0.5;
+ ctx.restore();
+ _assertSame(ctx.miterLimit, old, "ctx.miterLimit", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.miterLimit = 0.5;
+ old = ctx.miterLimit;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.miterLimit, old, "ctx.miterLimit", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.worker.js
new file mode 100644
index 0000000000..eb5adffe06
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.miterLimit.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.miterLimit
+// Description:save()/restore() works for miterLimit
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for miterLimit");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.miterLimit;
+ ctx.save();
+ ctx.miterLimit = 0.5;
+ ctx.restore();
+ _assertSame(ctx.miterLimit, old, "ctx.miterLimit", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.miterLimit = 0.5;
+ old = ctx.miterLimit;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ _assertSame(ctx.miterLimit, old, "ctx.miterLimit", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.html
new file mode 100644
index 0000000000..a86851af68
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.path</h1>
+<p class="desc">save()/restore() does not affect the current path</p>
+
+
+<script>
+var t = async_test("save()/restore() does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 100, 50);
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.worker.js
new file mode 100644
index 0000000000..d174de5a50
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.path.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.path
+// Description:save()/restore() does not affect the current path
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() does not affect the current path");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 100, 50);
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.html
new file mode 100644
index 0000000000..044ee1b4bb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.shadowBlur</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.shadowBlur</h1>
+<p class="desc">save()/restore() works for shadowBlur</p>
+
+
+<script>
+var t = async_test("save()/restore() works for shadowBlur");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowBlur;
+ ctx.save();
+ ctx.shadowBlur = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowBlur, old, "ctx.shadowBlur", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowBlur = 5;
+ old = ctx.shadowBlur;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowBlur, old, "ctx.shadowBlur", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.worker.js
new file mode 100644
index 0000000000..00cd6f8317
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowBlur.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.shadowBlur
+// Description:save()/restore() works for shadowBlur
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for shadowBlur");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowBlur;
+ ctx.save();
+ ctx.shadowBlur = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowBlur, old, "ctx.shadowBlur", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowBlur = 5;
+ old = ctx.shadowBlur;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowBlur, old, "ctx.shadowBlur", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.html
new file mode 100644
index 0000000000..0e8b4293e0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.shadowColor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.shadowColor</h1>
+<p class="desc">save()/restore() works for shadowColor</p>
+
+
+<script>
+var t = async_test("save()/restore() works for shadowColor");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowColor;
+ ctx.save();
+ ctx.shadowColor = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.shadowColor, old, "ctx.shadowColor", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowColor = "#ff0000";
+ old = ctx.shadowColor;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.shadowColor, old, "ctx.shadowColor", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.worker.js
new file mode 100644
index 0000000000..13c033f396
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowColor.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.shadowColor
+// Description:save()/restore() works for shadowColor
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for shadowColor");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowColor;
+ ctx.save();
+ ctx.shadowColor = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.shadowColor, old, "ctx.shadowColor", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowColor = "#ff0000";
+ old = ctx.shadowColor;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.shadowColor, old, "ctx.shadowColor", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.html
new file mode 100644
index 0000000000..11aa658f3e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.shadowOffsetX</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.shadowOffsetX</h1>
+<p class="desc">save()/restore() works for shadowOffsetX</p>
+
+
+<script>
+var t = async_test("save()/restore() works for shadowOffsetX");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetX;
+ ctx.save();
+ ctx.shadowOffsetX = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowOffsetX, old, "ctx.shadowOffsetX", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetX = 5;
+ old = ctx.shadowOffsetX;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowOffsetX, old, "ctx.shadowOffsetX", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.worker.js
new file mode 100644
index 0000000000..a6ad922647
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetX.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.shadowOffsetX
+// Description:save()/restore() works for shadowOffsetX
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for shadowOffsetX");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetX;
+ ctx.save();
+ ctx.shadowOffsetX = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowOffsetX, old, "ctx.shadowOffsetX", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetX = 5;
+ old = ctx.shadowOffsetX;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowOffsetX, old, "ctx.shadowOffsetX", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.html
new file mode 100644
index 0000000000..c238f0ec94
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.shadowOffsetY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.shadowOffsetY</h1>
+<p class="desc">save()/restore() works for shadowOffsetY</p>
+
+
+<script>
+var t = async_test("save()/restore() works for shadowOffsetY");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetY;
+ ctx.save();
+ ctx.shadowOffsetY = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowOffsetY, old, "ctx.shadowOffsetY", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetY = 5;
+ old = ctx.shadowOffsetY;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowOffsetY, old, "ctx.shadowOffsetY", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.worker.js
new file mode 100644
index 0000000000..323fcd1434
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.shadowOffsetY.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.shadowOffsetY
+// Description:save()/restore() works for shadowOffsetY
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for shadowOffsetY");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetY;
+ ctx.save();
+ ctx.shadowOffsetY = 5;
+ ctx.restore();
+ _assertSame(ctx.shadowOffsetY, old, "ctx.shadowOffsetY", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetY = 5;
+ old = ctx.shadowOffsetY;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ _assertSame(ctx.shadowOffsetY, old, "ctx.shadowOffsetY", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.html
new file mode 100644
index 0000000000..4a8750867f
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.stack</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.stack</h1>
+<p class="desc">save()/restore() can be nested as a stack</p>
+
+
+<script>
+var t = async_test("save()/restore() can be nested as a stack");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 1;
+ ctx.save();
+ ctx.lineWidth = 2;
+ ctx.save();
+ ctx.lineWidth = 3;
+ _assertSame(ctx.lineWidth, 3, "ctx.lineWidth", "3");
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 2, "ctx.lineWidth", "2");
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.worker.js
new file mode 100644
index 0000000000..460df4ec83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stack.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.stack
+// Description:save()/restore() can be nested as a stack
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() can be nested as a stack");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.lineWidth = 1;
+ ctx.save();
+ ctx.lineWidth = 2;
+ ctx.save();
+ ctx.lineWidth = 3;
+ _assertSame(ctx.lineWidth, 3, "ctx.lineWidth", "3");
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 2, "ctx.lineWidth", "2");
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 1, "ctx.lineWidth", "1");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.html
new file mode 100644
index 0000000000..d536155e64
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.stackdepth</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.stackdepth</h1>
+<p class="desc">save()/restore() stack depth is not unreasonably limited</p>
+
+
+<script>
+var t = async_test("save()/restore() stack depth is not unreasonably limited");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var limit = 512;
+ for (var i = 1; i < limit; ++i)
+ {
+ ctx.save();
+ ctx.lineWidth = i;
+ }
+ for (var i = limit-1; i > 0; --i)
+ {
+ _assertSame(ctx.lineWidth, i, "ctx.lineWidth", "i");
+ ctx.restore();
+ }
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.worker.js
new file mode 100644
index 0000000000..c494d9ddf8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.stackdepth.worker.js
@@ -0,0 +1,32 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.stackdepth
+// Description:save()/restore() stack depth is not unreasonably limited
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() stack depth is not unreasonably limited");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ var limit = 512;
+ for (var i = 1; i < limit; ++i)
+ {
+ ctx.save();
+ ctx.lineWidth = i;
+ }
+ for (var i = limit-1; i > 0; --i)
+ {
+ _assertSame(ctx.lineWidth, i, "ctx.lineWidth", "i");
+ ctx.restore();
+ }
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.html
new file mode 100644
index 0000000000..561205acd9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.strokeStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.strokeStyle</h1>
+<p class="desc">save()/restore() works for strokeStyle</p>
+
+
+<script>
+var t = async_test("save()/restore() works for strokeStyle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.strokeStyle;
+ ctx.save();
+ ctx.strokeStyle = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.strokeStyle, old, "ctx.strokeStyle", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.strokeStyle = "#ff0000";
+ old = ctx.strokeStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.strokeStyle, old, "ctx.strokeStyle", "old");
+ ctx.restore();
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.worker.js
new file mode 100644
index 0000000000..878a6d68cb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.strokeStyle.worker.js
@@ -0,0 +1,36 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.strokeStyle
+// Description:save()/restore() works for strokeStyle
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() works for strokeStyle");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Test that restore() undoes any modifications
+ var old = ctx.strokeStyle;
+ ctx.save();
+ ctx.strokeStyle = "#ff0000";
+ ctx.restore();
+ _assertSame(ctx.strokeStyle, old, "ctx.strokeStyle", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.strokeStyle = "#ff0000";
+ old = ctx.strokeStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ _assertSame(ctx.strokeStyle, old, "ctx.strokeStyle", "old");
+ ctx.restore();
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.html
new file mode 100644
index 0000000000..79ecdece53
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.transformation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.transformation</h1>
+<p class="desc">save()/restore() affects the current transformation matrix</p>
+
+
+<script>
+var t = async_test("save()/restore() affects the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.translate(200, 0);
+ ctx.restore();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(-200, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.worker.js
new file mode 100644
index 0000000000..1647dfb790
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.transformation.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.transformation
+// Description:save()/restore() affects the current transformation matrix
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("save()/restore() affects the current transformation matrix");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.translate(200, 0);
+ ctx.restore();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(-200, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.html b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.html
new file mode 100644
index 0000000000..a6713adde2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.state.saverestore.underflow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.state.saverestore.underflow</h1>
+<p class="desc">restore() with an empty stack has no effect</p>
+
+
+<script>
+var t = async_test("restore() with an empty stack has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ for (var i = 0; i < 16; ++i)
+ ctx.restore();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 0.5, "ctx.lineWidth", "0.5");
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.worker.js b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.worker.js
new file mode 100644
index 0000000000..8ed4bcbc10
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/the-canvas-state/2d.state.saverestore.underflow.worker.js
@@ -0,0 +1,26 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.state.saverestore.underflow
+// Description:restore() with an empty stack has no effect
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("restore() with an empty stack has no effect");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ for (var i = 0; i < 16; ++i)
+ ctx.restore();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ _assertSame(ctx.lineWidth, 0.5, "ctx.lineWidth", "0.5");
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.html
new file mode 100644
index 0000000000..d438c27433
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.order</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.order</h1>
+<p class="desc">Transformations are applied in the right order</p>
+
+
+<script>
+var t = async_test("Transformations are applied in the right order");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 1);
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -50, 50, 50);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.worker.js
new file mode 100644
index 0000000000..219cbe8421
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.order.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.order
+// Description:Transformations are applied in the right order
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Transformations are applied in the right order");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 1);
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -50, 50, 50);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.html
new file mode 100644
index 0000000000..fb0f295062
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotate.direction</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotate.direction</h1>
+<p class="desc">rotate() is clockwise</p>
+
+
+<script>
+var t = async_test("rotate() is clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -100, 50, 100);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.worker.js
new file mode 100644
index 0000000000..b92b7d8368
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.direction.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate.direction
+// Description:rotate() is clockwise
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate() is clockwise");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -100, 50, 100);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.html
new file mode 100644
index 0000000000..dbde38370d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotate.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotate.nonfinite</h1>
+<p class="desc">rotate() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("rotate() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.rotate(Infinity);
+ ctx.rotate(-Infinity);
+ ctx.rotate(NaN);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.worker.js
new file mode 100644
index 0000000000..52b6605e45
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.nonfinite.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate.nonfinite
+// Description:rotate() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.rotate(Infinity);
+ ctx.rotate(-Infinity);
+ ctx.rotate(NaN);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.html
new file mode 100644
index 0000000000..28006028ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotate.radians</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotate.radians</h1>
+<p class="desc">rotate() uses radians</p>
+
+
+<script>
+var t = async_test("rotate() uses radians");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.worker.js
new file mode 100644
index 0000000000..0851691156
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.radians.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate.radians
+// Description:rotate() uses radians
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate() uses radians");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.html
new file mode 100644
index 0000000000..aea14ceddf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotate.wrap</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotate.wrap</h1>
+<p class="desc">rotate() wraps large positive values correctly</p>
+
+
+<script>
+var t = async_test("rotate() wraps large positive values correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi)
+ // We need about pi +/- 0.001 in order to get correct-looking results
+ // 32-bit floats can store pi*4097 with precision 2^-10, so that should
+ // be safe enough on reasonable implementations
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,2, 0,255,0,255);
+ _assertPixel(canvas, 98,47, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.worker.js
new file mode 100644
index 0000000000..4d0c2f5b5d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrap.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate.wrap
+// Description:rotate() wraps large positive values correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate() wraps large positive values correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi)
+ // We need about pi +/- 0.001 in order to get correct-looking results
+ // 32-bit floats can store pi*4097 with precision 2^-10, so that should
+ // be safe enough on reasonable implementations
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,2, 0,255,0,255);
+ _assertPixel(canvas, 98,47, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.html
new file mode 100644
index 0000000000..7363007a4d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotate.wrapnegative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotate.wrapnegative</h1>
+<p class="desc">rotate() wraps large negative values correctly</p>
+
+
+<script>
+var t = async_test("rotate() wraps large negative values correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(-Math.PI * (1 + 4096));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,2, 0,255,0,255);
+ _assertPixel(canvas, 98,47, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.worker.js
new file mode 100644
index 0000000000..932ecf6512
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.wrapnegative.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate.wrapnegative
+// Description:rotate() wraps large negative values correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate() wraps large negative values correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(-Math.PI * (1 + 4096));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ _assertPixel(canvas, 98,2, 0,255,0,255);
+ _assertPixel(canvas, 98,47, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.html
new file mode 100644
index 0000000000..965d0e0768
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.rotate.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.rotate.zero</h1>
+<p class="desc">rotate() by 0 does nothing</p>
+
+
+<script>
+var t = async_test("rotate() by 0 does nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.worker.js
new file mode 100644
index 0000000000..659c9fd7a0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.rotate.zero
+// Description:rotate() by 0 does nothing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("rotate() by 0 does nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.html
new file mode 100644
index 0000000000..d4063f7129
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.scale.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.scale.basic</h1>
+<p class="desc">scale() works</p>
+
+
+<script>
+var t = async_test("scale() works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 4);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 12.5);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.worker.js
new file mode 100644
index 0000000000..5e79daf3f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.basic.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.scale.basic
+// Description:scale() works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("scale() works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 4);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 12.5);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.html
new file mode 100644
index 0000000000..ae8f954a71
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.scale.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.scale.large</h1>
+<p class="desc">scale() with large scale factors works</p>
+
+<p class="notes">Not really that large at all, but it hits the limits in Firefox.
+<script>
+var t = async_test("scale() with large scale factors works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(1e5, 1e5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 1, 1);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.worker.js
new file mode 100644
index 0000000000..6d71627728
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.large.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.scale.large
+// Description:scale() with large scale factors works
+// Note:<p class="notes">Not really that large at all, but it hits the limits in Firefox.
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("scale() with large scale factors works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(1e5, 1e5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 1, 1);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.html
new file mode 100644
index 0000000000..6a899d1dd6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.scale.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.scale.multiple</h1>
+<p class="desc">Multiple scale()s combine</p>
+
+
+<script>
+var t = async_test("Multiple scale()s combine");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.worker.js
new file mode 100644
index 0000000000..921e95aa72
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.multiple.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.scale.multiple
+// Description:Multiple scale()s combine
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Multiple scale()s combine");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.html
new file mode 100644
index 0000000000..68c5780332
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.scale.negative</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.scale.negative</h1>
+<p class="desc">scale() with negative scale factors works</p>
+
+
+<script>
+var t = async_test("scale() with negative scale factors works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.scale(-1, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.scale(1, -1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, -50, 50, 50);
+ ctx.restore();
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.worker.js
new file mode 100644
index 0000000000..cb0f01c618
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.negative.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.scale.negative
+// Description:scale() with negative scale factors works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("scale() with negative scale factors works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.scale(-1, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.scale(1, -1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, -50, 50, 50);
+ ctx.restore();
+ _assertPixel(canvas, 25,25, 0,255,0,255);
+ _assertPixel(canvas, 75,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.html
new file mode 100644
index 0000000000..5fd95629c9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.scale.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.scale.nonfinite</h1>
+<p class="desc">scale() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("scale() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.scale(Infinity, 0.1);
+ ctx.scale(-Infinity, 0.1);
+ ctx.scale(NaN, 0.1);
+ ctx.scale(0.1, Infinity);
+ ctx.scale(0.1, -Infinity);
+ ctx.scale(0.1, NaN);
+ ctx.scale(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.worker.js
new file mode 100644
index 0000000000..35f9c90e71
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.nonfinite.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.scale.nonfinite
+// Description:scale() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("scale() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.scale(Infinity, 0.1);
+ ctx.scale(-Infinity, 0.1);
+ ctx.scale(NaN, 0.1);
+ ctx.scale(0.1, Infinity);
+ ctx.scale(0.1, -Infinity);
+ ctx.scale(0.1, NaN);
+ ctx.scale(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.html
new file mode 100644
index 0000000000..b4269bd140
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.scale.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.scale.zero</h1>
+<p class="desc">scale() with a scale factor of zero works</p>
+
+
+<script>
+var t = async_test("scale() with a scale factor of zero works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.scale(0, 1);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.translate(0, 25);
+ ctx.scale(1, 0);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.worker.js
new file mode 100644
index 0000000000..9e90127cfe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.scale.zero.worker.js
@@ -0,0 +1,39 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.scale.zero
+// Description:scale() with a scale factor of zero works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("scale() with a scale factor of zero works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.scale(0, 1);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.translate(0, 25);
+ ctx.scale(1, 0);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.html
new file mode 100644
index 0000000000..0395c561bf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.setTransform.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.setTransform.multiple</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.setTransform(1/2,0, 0,1/2, 0,0);
+ ctx.setTransform();
+ ctx.setTransform(2,0, 0,2, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ _assertPixel(canvas, 75,35, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.worker.js
new file mode 100644
index 0000000000..e3e6daf878
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.multiple.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.setTransform.multiple
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.setTransform(1/2,0, 0,1/2, 0,0);
+ ctx.setTransform();
+ ctx.setTransform(2,0, 0,2, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ _assertPixel(canvas, 75,35, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.html
new file mode 100644
index 0000000000..474b20a10b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.setTransform.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.setTransform.nonfinite</h1>
+<p class="desc">setTransform() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("setTransform() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(NaN, 0, 0, 0, 0, 0);
+ ctx.setTransform(0, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, -Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, NaN, 0, 0, 0, 0);
+ ctx.setTransform(0, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, -Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, NaN, 0, 0, 0);
+ ctx.setTransform(0, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, -Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, NaN, 0, 0);
+ ctx.setTransform(0, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, -Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, NaN, 0);
+ ctx.setTransform(0, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, -Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, NaN);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.worker.js
new file mode 100644
index 0000000000..d99ea52dea
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.nonfinite.worker.js
@@ -0,0 +1,105 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.setTransform.nonfinite
+// Description:setTransform() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("setTransform() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(NaN, 0, 0, 0, 0, 0);
+ ctx.setTransform(0, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, -Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, NaN, 0, 0, 0, 0);
+ ctx.setTransform(0, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, -Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, NaN, 0, 0, 0);
+ ctx.setTransform(0, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, -Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, NaN, 0, 0);
+ ctx.setTransform(0, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, -Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, NaN, 0);
+ ctx.setTransform(0, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, -Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, NaN);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.html
new file mode 100644
index 0000000000..2d24d61f4b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.setTransform.skewed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.setTransform.skewed</h1>
+<p class="desc"></p>
+
+
+<script>
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.setTransform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ _assertPixel(canvas, 21,11, 0,255,0,255);
+ _assertPixel(canvas, 79,11, 0,255,0,255);
+ _assertPixel(canvas, 21,39, 0,255,0,255);
+ _assertPixel(canvas, 79,39, 0,255,0,255);
+ _assertPixel(canvas, 39,19, 0,255,0,255);
+ _assertPixel(canvas, 61,19, 0,255,0,255);
+ _assertPixel(canvas, 39,31, 0,255,0,255);
+ _assertPixel(canvas, 61,31, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.worker.js
new file mode 100644
index 0000000000..161f4087e5
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.setTransform.skewed.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.setTransform.skewed
+// Description:
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.setTransform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ _assertPixel(canvas, 21,11, 0,255,0,255);
+ _assertPixel(canvas, 79,11, 0,255,0,255);
+ _assertPixel(canvas, 21,39, 0,255,0,255);
+ _assertPixel(canvas, 79,39, 0,255,0,255);
+ _assertPixel(canvas, 39,19, 0,255,0,255);
+ _assertPixel(canvas, 61,19, 0,255,0,255);
+ _assertPixel(canvas, 39,31, 0,255,0,255);
+ _assertPixel(canvas, 61,31, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.html
new file mode 100644
index 0000000000..d88b3bc03c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.transform.identity</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.transform.identity</h1>
+<p class="desc">transform() with the identity matrix does nothing</p>
+
+
+<script>
+var t = async_test("transform() with the identity matrix does nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,0, 0,1, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.worker.js
new file mode 100644
index 0000000000..67202628c6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.identity.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.transform.identity
+// Description:transform() with the identity matrix does nothing
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("transform() with the identity matrix does nothing");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,0, 0,1, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.html
new file mode 100644
index 0000000000..a7dfbe5f34
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.transform.multiply</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.transform.multiply</h1>
+<p class="desc">transform() multiplies the CTM</p>
+
+
+<script>
+var t = async_test("transform() multiplies the CTM");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,2, 3,4, 5,6);
+ ctx.transform(-2,1, 3/2,-1/2, 1,-2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.worker.js
new file mode 100644
index 0000000000..aa89a7d8ca
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.multiply.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.transform.multiply
+// Description:transform() multiplies the CTM
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("transform() multiplies the CTM");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,2, 3,4, 5,6);
+ ctx.transform(-2,1, 3/2,-1/2, 1,-2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.html
new file mode 100644
index 0000000000..c4cd459c8b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.transform.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.transform.nonfinite</h1>
+<p class="desc">transform() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("transform() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.transform(Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(NaN, 0, 0, 0, 0, 0);
+ ctx.transform(0, Infinity, 0, 0, 0, 0);
+ ctx.transform(0, -Infinity, 0, 0, 0, 0);
+ ctx.transform(0, NaN, 0, 0, 0, 0);
+ ctx.transform(0, 0, Infinity, 0, 0, 0);
+ ctx.transform(0, 0, -Infinity, 0, 0, 0);
+ ctx.transform(0, 0, NaN, 0, 0, 0);
+ ctx.transform(0, 0, 0, Infinity, 0, 0);
+ ctx.transform(0, 0, 0, -Infinity, 0, 0);
+ ctx.transform(0, 0, 0, NaN, 0, 0);
+ ctx.transform(0, 0, 0, 0, Infinity, 0);
+ ctx.transform(0, 0, 0, 0, -Infinity, 0);
+ ctx.transform(0, 0, 0, 0, NaN, 0);
+ ctx.transform(0, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, 0, -Infinity);
+ ctx.transform(0, 0, 0, 0, 0, NaN);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.worker.js
new file mode 100644
index 0000000000..c96af44b59
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.nonfinite.worker.js
@@ -0,0 +1,105 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.transform.nonfinite
+// Description:transform() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("transform() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.transform(Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(NaN, 0, 0, 0, 0, 0);
+ ctx.transform(0, Infinity, 0, 0, 0, 0);
+ ctx.transform(0, -Infinity, 0, 0, 0, 0);
+ ctx.transform(0, NaN, 0, 0, 0, 0);
+ ctx.transform(0, 0, Infinity, 0, 0, 0);
+ ctx.transform(0, 0, -Infinity, 0, 0, 0);
+ ctx.transform(0, 0, NaN, 0, 0, 0);
+ ctx.transform(0, 0, 0, Infinity, 0, 0);
+ ctx.transform(0, 0, 0, -Infinity, 0, 0);
+ ctx.transform(0, 0, 0, NaN, 0, 0);
+ ctx.transform(0, 0, 0, 0, Infinity, 0);
+ ctx.transform(0, 0, 0, 0, -Infinity, 0);
+ ctx.transform(0, 0, 0, 0, NaN, 0);
+ ctx.transform(0, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, 0, -Infinity);
+ ctx.transform(0, 0, 0, 0, 0, NaN);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.html
new file mode 100644
index 0000000000..2f3c0453e3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.transform.skewed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.transform.skewed</h1>
+<p class="desc">transform() with skewy matrix transforms correctly</p>
+
+
+<script>
+var t = async_test("transform() with skewy matrix transforms correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.transform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ _assertPixel(canvas, 21,11, 0,255,0,255);
+ _assertPixel(canvas, 79,11, 0,255,0,255);
+ _assertPixel(canvas, 21,39, 0,255,0,255);
+ _assertPixel(canvas, 79,39, 0,255,0,255);
+ _assertPixel(canvas, 39,19, 0,255,0,255);
+ _assertPixel(canvas, 61,19, 0,255,0,255);
+ _assertPixel(canvas, 39,31, 0,255,0,255);
+ _assertPixel(canvas, 61,31, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.worker.js
new file mode 100644
index 0000000000..c7ebaf9a83
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.transform.skewed.worker.js
@@ -0,0 +1,50 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.transform.skewed
+// Description:transform() with skewy matrix transforms correctly
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("transform() with skewy matrix transforms correctly");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.transform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ _assertPixel(canvas, 21,11, 0,255,0,255);
+ _assertPixel(canvas, 79,11, 0,255,0,255);
+ _assertPixel(canvas, 21,39, 0,255,0,255);
+ _assertPixel(canvas, 79,39, 0,255,0,255);
+ _assertPixel(canvas, 39,19, 0,255,0,255);
+ _assertPixel(canvas, 61,19, 0,255,0,255);
+ _assertPixel(canvas, 39,31, 0,255,0,255);
+ _assertPixel(canvas, 61,31, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.html
new file mode 100644
index 0000000000..f68225c077
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.translate.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.translate.basic</h1>
+<p class="desc">translate() works</p>
+
+
+<script>
+var t = async_test("translate() works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.worker.js
new file mode 100644
index 0000000000..f377ab8a48
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.basic.worker.js
@@ -0,0 +1,28 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.translate.basic
+// Description:translate() works
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("translate() works");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ _assertPixel(canvas, 90,40, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.html b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.html
new file mode 100644
index 0000000000..ebab949b4c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.transformation.translate.nonfinite</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.transformation.translate.nonfinite</h1>
+<p class="desc">translate() with Infinity/NaN is ignored</p>
+
+
+<script>
+var t = async_test("translate() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.translate(Infinity, 0.1);
+ ctx.translate(-Infinity, 0.1);
+ ctx.translate(NaN, 0.1);
+ ctx.translate(0.1, Infinity);
+ ctx.translate(0.1, -Infinity);
+ ctx.translate(0.1, NaN);
+ ctx.translate(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.worker.js b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.worker.js
new file mode 100644
index 0000000000..7ad6fce2ba
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.translate.nonfinite.worker.js
@@ -0,0 +1,37 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.transformation.translate.nonfinite
+// Description:translate() with Infinity/NaN is ignored
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("translate() with Infinity/NaN is ignored");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.translate(Infinity, 0.1);
+ ctx.translate(-Infinity, 0.1);
+ ctx.translate(NaN, 0.1);
+ ctx.translate(0.1, Infinity);
+ ctx.translate(0.1, -Infinity);
+ ctx.translate(0.1, NaN);
+ ctx.translate(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ _assertPixel(canvas, 50,25, 0,255,0,255);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.html b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.html
new file mode 100644
index 0000000000..e1391e9010
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.color.space.p3.to.p3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.color.space.p3.to.p3</h1>
+<p class="desc">test getImageData with display-p3 and uint8 from display p3 uint8 canvas</p>
+
+
+<script>
+var t = async_test("test getImageData with display-p3 and uint8 from display p3 uint8 canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d', {colorSpace: "display-p3"});
+
+ var color_style = 'rgb(50, 100, 150)';
+ // [0.24304, 0.38818, 0.57227, 1.0] * 255 = [62, 99, 146, 255]
+ var pixel_expected = [62, 99, 146, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "display-p3", storageFormat: "uint8"}).data;
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.worker.js b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.worker.js
new file mode 100644
index 0000000000..844cd93f81
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.p3.worker.js
@@ -0,0 +1,34 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.color.space.p3.to.p3
+// Description:test getImageData with display-p3 and uint8 from display p3 uint8 canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("test getImageData with display-p3 and uint8 from display p3 uint8 canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d', {colorSpace: "display-p3"});
+
+ var color_style = 'rgb(50, 100, 150)';
+ // [0.24304, 0.38818, 0.57227, 1.0] * 255 = [62, 99, 146, 255]
+ var pixel_expected = [62, 99, 146, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "display-p3", storageFormat: "uint8"}).data;
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.html b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.html
new file mode 100644
index 0000000000..0628744421
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.color.space.p3.to.srgb</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.color.space.p3.to.srgb</h1>
+<p class="desc">test getImageData with srsb and uint8 from display p3 uint8 canvas</p>
+
+
+<script>
+var t = async_test("test getImageData with srsb and uint8 from display p3 uint8 canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d', {colorSpace: "display-p3"});
+
+ var color_style = 'rgb(50, 100, 150)';
+ var pixel_expected = [50, 100, 150, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "srgb", storageFormat: "uint8"}).data;
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+ t.done();
+
+});
+</script>
diff --git a/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.worker.js b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.worker.js
new file mode 100644
index 0000000000..619c59076d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.worker.js
@@ -0,0 +1,33 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.color.space.p3.to.srgb
+// Description:test getImageData with srsb and uint8 from display p3 uint8 canvas
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("test getImageData with srsb and uint8 from display p3 uint8 canvas");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+
+ var canvas = new OffscreenCanvas(100, 50);
+ var ctx = canvas.getContext('2d', {colorSpace: "display-p3"});
+
+ var color_style = 'rgb(50, 100, 150)';
+ var pixel_expected = [50, 100, 150, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "srgb", storageFormat: "uint8"}).data;
+ _assertSame(pixel.length, pixel_expected.length, "pixel.length", "pixel_expected.length");
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+ t.done();
+});
+done();
diff --git a/testing/web-platform/tests/html/canvas/resources/2x2.png b/testing/web-platform/tests/html/canvas/resources/2x2.png
new file mode 100644
index 0000000000..9be31562b3
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/2x2.png
Binary files differ
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-frame.css b/testing/web-platform/tests/html/canvas/resources/canvas-frame.css
new file mode 100644
index 0000000000..0c97a680d1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-frame.css
@@ -0,0 +1,21 @@
+body {
+ font-size: small;
+ font-family: sans-serif;
+}
+
+p {
+ line-height: 0;
+}
+
+p:first-child {
+ display: inline;
+}
+
+h1 {
+ display: inline;
+}
+
+iframe, object {
+ border: 1px black solid;
+ margin: 2px;
+}
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-frame.css.headers b/testing/web-platform/tests/html/canvas/resources/canvas-frame.css.headers
new file mode 100644
index 0000000000..e13897f157
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-frame.css.headers
@@ -0,0 +1 @@
+Content-Type: text/css; charset=utf-8
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-index.css b/testing/web-platform/tests/html/canvas/resources/canvas-index.css
new file mode 100644
index 0000000000..ef35864bc0
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-index.css
@@ -0,0 +1,31 @@
+body {
+ font-size: small;
+ font-family: sans-serif;
+}
+
+a {
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+h3 {
+ display: inline;
+ font-size: medium;
+}
+
+h3 + p {
+ display: inline;
+ margin-left: 0.5em;
+}
+
+li {
+ list-style-type: none;
+}
+
+ul {
+ padding-left: 2em;
+ margin-left: 0;
+}
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-index.css.headers b/testing/web-platform/tests/html/canvas/resources/canvas-index.css.headers
new file mode 100644
index 0000000000..e13897f157
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-index.css.headers
@@ -0,0 +1 @@
+Content-Type: text/css; charset=utf-8
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-spec.css b/testing/web-platform/tests/html/canvas/resources/canvas-spec.css
new file mode 100644
index 0000000000..5882acb68e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-spec.css
@@ -0,0 +1,50 @@
+.testrefs {
+ font-size: small;
+ margin-left: 0.2em;
+ margin-right: 0.2em;
+ border-bottom: none !important;
+
+ font-weight: normal;
+ font-style: normal;
+ white-space: normal;
+ font-family: sans-serif;
+}
+
+.kw-must, .kw-required {
+ background: #fda;
+}
+
+.kw-should {
+ background: #ffa;
+}
+
+.kw-none {
+ background: #dfa;
+}
+
+
+pre.idl .testrefs :link {
+ color: #00c;
+}
+
+pre.idl .testrefs :visited {
+ color: #609;
+}
+
+.testrefs a:hover {
+ background: transparent;
+ text-decoration: none;
+}
+
+.testrefs:before {
+ content: '[';
+}
+
+.testrefs:after {
+ content: ']';
+}
+
+.testrefs a:first-child {
+ font-weight: bold;
+ text-decoration: none;
+}
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-spec.css.headers b/testing/web-platform/tests/html/canvas/resources/canvas-spec.css.headers
new file mode 100644
index 0000000000..e13897f157
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-spec.css.headers
@@ -0,0 +1 @@
+Content-Type: text/css; charset=utf-8
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-tests.css b/testing/web-platform/tests/html/canvas/resources/canvas-tests.css
new file mode 100644
index 0000000000..e006e812de
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-tests.css
@@ -0,0 +1,134 @@
+html.fail {
+ background: #f66;
+}
+html.pass {
+ background: #6f6;
+}
+html.needs_check {
+ background: #99f;
+}
+
+body {
+ font-size: small;
+ font-family: sans-serif;
+ color: black;
+}
+
+a:link {
+ color: #00c;
+}
+a:visited {
+ color: #808;
+}
+
+body.framed {
+ font-size: x-small;
+}
+
+h1 {
+ font-size: larger;
+ margin: 0;
+ padding-left: 0.5em;
+ text-indent: -0.5em;
+}
+
+p {
+ margin: 0;
+}
+
+p.notes {
+ margin-bottom: 0.5em;
+ font-style: italic;
+}
+
+ul {
+ margin: 0;
+ margin-bottom: 0.5em;
+ padding: 0;
+ padding-left: 1em;
+}
+
+.refs {
+ font-style: italic;
+ margin-bottom: 0.5em;
+}
+
+.refs ul {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+
+.refs li {
+ display: inline;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+canvas {
+ display: none;
+ visibility: hidden;
+ border: 2px #f0f solid;
+ background: url(../images/background.png);
+}
+
+img.expected {
+ display: none;
+ border: 2px #f0f solid;
+ background: url(../images/background.png);
+}
+
+iframe {
+ border: 2px #f0f solid;
+}
+
+.output {
+ display: none;
+}
+
+.show_output .output, .needs_check .output {
+ display: block !important;
+ visibility: visible !important;
+}
+
+.show_output #show_output {
+ display: none;
+}
+
+.resource {
+ visibility: hidden;
+ height: 0;
+}
+
+.fallback {
+ font-size: 2em;
+ font-weight: bold;
+ color: #a00;
+}
+
+
+html.minimal body {
+ color: white;
+}
+html.fail.minimal {
+ background: #f00;
+}
+html.pass.minimal {
+ background: #080;
+}
+html.needs_check.minimal {
+ background: #008;
+}
+.minimal #d {
+ display: none !important;
+}
+.minimal .expectedtext {
+ visibility: hidden !important;
+}
+#passtext, #failtext {
+ display: none;
+}
+.minimal.pass #passtext, .minimal.fail #failtext {
+ display: block;
+}
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-tests.css.headers b/testing/web-platform/tests/html/canvas/resources/canvas-tests.css.headers
new file mode 100644
index 0000000000..e13897f157
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-tests.css.headers
@@ -0,0 +1 @@
+Content-Type: text/css; charset=utf-8
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-tests.js b/testing/web-platform/tests/html/canvas/resources/canvas-tests.js
new file mode 100644
index 0000000000..c6e2873283
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-tests.js
@@ -0,0 +1,221 @@
+function _valToString(val)
+{
+ if (val === undefined || val === null)
+ return '[' + typeof(val) + ']';
+ return val.toString() + '[' + typeof(val) + ']';
+}
+
+function _assert(cond, text)
+{
+ assert_true(!!cond, text);
+}
+
+function _assertSame(a, b, text_a, text_b)
+{
+ var msg = text_a + ' === ' + text_b + ' (got ' + _valToString(a) +
+ ', expected ' + _valToString(b) + ')';
+ assert_equals(a, b, msg);
+}
+
+function _assertDifferent(a, b, text_a, text_b)
+{
+ var msg = text_a + ' !== ' + text_b + ' (got ' + _valToString(a) +
+ ', expected not ' + _valToString(b) + ')';
+ assert_not_equals(a, b, msg);
+}
+
+
+function _getPixel(canvas, x,y)
+{
+ var ctx = canvas.getContext('2d');
+ var imgdata = ctx.getImageData(x, y, 1, 1);
+ return [ imgdata.data[0], imgdata.data[1], imgdata.data[2], imgdata.data[3] ];
+}
+
+function _assertPixel(canvas, x, y, r, g, b, a)
+{
+ var c = _getPixel(canvas, x,y);
+ assert_equals(c[0], r, 'Red channel of the pixel at (' + x + ', ' + y + ')');
+ assert_equals(c[1], g, 'Green channel of the pixel at (' + x + ', ' + y + ')');
+ assert_equals(c[2], b, 'Blue channel of the pixel at (' + x + ', ' + y + ')');
+ assert_equals(c[3], a, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');
+}
+
+function _assertPixelApprox(canvas, x, y, r, g, b, a, tolerance)
+{
+ var c = _getPixel(canvas, x,y);
+ assert_approx_equals(c[0], r, tolerance, 'Red channel of the pixel at (' + x + ', ' + y + ')');
+ assert_approx_equals(c[1], g, tolerance, 'Green channel of the pixel at (' + x + ', ' + y + ')');
+ assert_approx_equals(c[2], b, tolerance, 'Blue channel of the pixel at (' + x + ', ' + y + ')');
+ assert_approx_equals(c[3], a, tolerance, 'Alpha channel of the pixel at (' + x + ', ' + y + ')');
+}
+
+function _assertMatricesApproxEqual(matA, matB)
+{
+ A = matA.toFloat32Array();
+ B = matB.toFloat32Array();
+ assert_equals(A.length, B.length);
+ for (var i = 0; i < A.length; i++) {
+ assert_approx_equals(A[i], B[i], 10e-6);
+ }
+}
+
+function rad2deg(angle_in_radians) {
+ return angle_in_radians / Math.PI * 180;
+}
+
+function deg2rad(angle_in_degrees) {
+ return angle_in_degrees / 180 * Math.PI;
+}
+
+let _deferred = false;
+
+function deferTest() {
+ _deferred = true;
+}
+
+function _addTest(testFn, attributes={})
+{
+ on_event(window, "load", function()
+ {
+ t.step(function() {
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d', attributes);
+ t.step(testFn, window, canvas, ctx);
+ });
+
+ if (!_deferred) {
+ t.done();
+ }
+ });
+}
+
+function _assertGreen(ctx, canvasWidth, canvasHeight)
+{
+ var testColor = function(d, idx, expected) {
+ assert_equals(d[idx], expected, "d[" + idx + "]", String(expected));
+ };
+ var imagedata = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
+ var w = imagedata.width, h = imagedata.height, d = imagedata.data;
+ for (var i = 0; i < h; ++i) {
+ for (var j = 0; j < w; ++j) {
+ testColor(d, 4 * (w * i + j) + 0, 0);
+ testColor(d, 4 * (w * i + j) + 1, 255);
+ testColor(d, 4 * (w * i + j) + 2, 0);
+ testColor(d, 4 * (w * i + j) + 3, 255);
+ }
+ }
+}
+
+function addCrossOriginYellowImage()
+{
+ var img = new Image();
+ img.id = "yellow.png";
+ img.className = "resource";
+ img.src = get_host_info().HTTP_REMOTE_ORIGIN + "/images/yellow.png";
+ document.body.appendChild(img);
+}
+
+function addCrossOriginRedirectYellowImage()
+{
+ var img = new Image();
+ img.id = "yellow.png";
+ img.className = "resource";
+ img.src = get_host_info().HTTP_ORIGIN + "/common/redirect.py?location=" +
+ get_host_info().HTTP_REMOTE_ORIGIN + "/images/yellow.png";
+ document.body.appendChild(img);
+}
+
+function forEachCanvasSource(crossOriginUrl, sameOriginUrl, callback) {
+ function makeImage() {
+ return new Promise((resolve, reject) => {
+ const image = new Image();
+ image.onload = () => resolve(image);
+ image.onerror = reject;
+ image.src = crossOriginUrl + "/images/red.png";
+ });
+ }
+
+ const arguments = [
+ {
+ name: "cross-origin HTMLImageElement",
+ factory: makeImage,
+ },
+
+ {
+ name: "cross-origin SVGImageElement",
+ factory: () => {
+ return new Promise((resolve, reject) => {
+ const image = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ image.onload = () => resolve(image);
+ image.onerror = reject;
+ image.setAttribute("externalResourcesRequired", "true");
+ image.setAttributeNS("http://www.w3.org/1999/xlink", 'xlink:href', crossOriginUrl + "/images/red.png");
+ document.body.appendChild(image);
+ });
+ },
+ },
+
+ {
+ name: "cross-origin HTMLVideoElement",
+ factory: () => {
+ return new Promise((resolve, reject) => {
+ const video = document.createElement("video");
+ video.oncanplaythrough = () => resolve(video);
+ video.preload = "auto";
+ video.onerror = reject;
+ video.src = getVideoURI(crossOriginUrl + "/media/movie_300");
+ });
+ },
+ },
+
+ {
+ name: "redirected to cross-origin HTMLVideoElement",
+ factory: () => {
+ return new Promise((resolve, reject) => {
+ const video = document.createElement("video");
+ video.oncanplaythrough = () => resolve(video);
+ video.preload = "auto";
+ video.onerror = reject;
+ video.src = "/common/redirect.py?location=" + getVideoURI(crossOriginUrl + "/media/movie_300");
+ });
+ },
+ },
+
+ {
+ name: "redirected to same-origin HTMLVideoElement",
+ factory: () => {
+ return new Promise((resolve, reject) => {
+ const video = document.createElement("video");
+ video.oncanplaythrough = () => resolve(video);
+ video.preload = "auto";
+ video.onerror = reject;
+ video.src = crossOriginUrl + "/common/redirect.py?location=" + getVideoURI(sameOriginUrl + "/media/movie_300");
+ });
+ },
+ },
+
+ {
+ name: "unclean HTMLCanvasElement",
+ factory: () => {
+ return makeImage().then(image => {
+ const canvas = document.createElement("canvas");
+ const context = canvas.getContext("2d");
+ context.drawImage(image, 0, 0);
+ return canvas;
+ });
+ },
+ },
+
+ {
+ name: "unclean ImageBitmap",
+ factory: () => {
+ return makeImage().then(createImageBitmap);
+ },
+ },
+ ];
+
+ for (let { name, factory } of arguments) {
+ callback(name, factory);
+ }
+}
diff --git a/testing/web-platform/tests/html/canvas/resources/canvas-tests.js.headers b/testing/web-platform/tests/html/canvas/resources/canvas-tests.js.headers
new file mode 100644
index 0000000000..6805c323df
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/resources/canvas-tests.js.headers
@@ -0,0 +1 @@
+Content-Type: text/javascript; charset=utf-8
diff --git a/testing/web-platform/tests/html/canvas/tools/gentest.py b/testing/web-platform/tests/html/canvas/tools/gentest.py
new file mode 100644
index 0000000000..36cb7fe0f6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/gentest.py
@@ -0,0 +1,18 @@
+# To use this script:
+# -make a python virtual environment somewhere (it doesn't matter where)
+# python3 -m venv venv
+# -enter the virtual environment
+# source venv/bin/activate
+# -install required packages in the venv
+# pip3 install cairocffi jinja2 pyyaml
+# -change to the directory with this script and run it
+# python3 gentest.py
+
+from gentestutils import genTestUtils
+from gentestutilsunion import genTestUtils_union
+
+genTestUtils('../element', '../element', 'templates.yaml',
+ 'name2dir-canvas.yaml', False)
+genTestUtils('../offscreen', '../offscreen', 'templates.yaml',
+ 'name2dir-offscreen.yaml', True)
+genTestUtils_union('name2dir.yaml')
diff --git a/testing/web-platform/tests/html/canvas/tools/gentest_union.py b/testing/web-platform/tests/html/canvas/tools/gentest_union.py
new file mode 100644
index 0000000000..38a37a81ac
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/gentest_union.py
@@ -0,0 +1,3 @@
+from gentestutilsunion import genTestUtils_union
+
+genTestUtils_union('name2dir.yaml')
diff --git a/testing/web-platform/tests/html/canvas/tools/gentestutils.py b/testing/web-platform/tests/html/canvas/tools/gentestutils.py
new file mode 100644
index 0000000000..8fa33e3975
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/gentestutils.py
@@ -0,0 +1,369 @@
+# Current code status:
+#
+# This was originally written by Philip Taylor for use at
+# http://philip.html5.org/tests/canvas/suite/tests/
+#
+# It has been adapted for use with the Web Platform Test Suite suite at
+# https://github.com/web-platform-tests/wpt/
+#
+# The original version had a number of now-removed features (multiple versions
+# of each test case of varying verbosity, Mozilla mochitests, semi-automated
+# test harness). It also had a different directory structure.
+
+# To update or add test cases:
+#
+# * Modify the tests*.yaml files.
+# - 'name' is an arbitrary hierarchical name to help categorise tests.
+# - 'desc' is a rough description of what behaviour the test aims to test.
+# - 'code' is JavaScript code to execute, with some special commands starting
+# with '@'
+# - 'expected' is what the final canvas output should be: a string 'green' or
+# 'clear' (100x50 images in both cases), or a string 'size 100 50' (or any
+# other size) followed by Python code using Pycairo to generate the image.
+#
+# * Run "./build.sh".
+# This requires a few Python modules which might not be ubiquitous.
+# It will usually emit some warnings, which ideally should be fixed but can
+# generally be safely ignored.
+#
+# * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
+
+from typing import List, Mapping
+
+import re
+import importlib
+import os
+import pathlib
+import sys
+import textwrap
+
+try:
+ import cairocffi as cairo # type: ignore
+except ImportError:
+ import cairo
+
+try:
+ # Compatible and lots faster.
+ import syck as yaml # type: ignore
+except ImportError:
+ import yaml
+
+
+class Error(Exception):
+ """Base class for all exceptions raised by this module"""
+
+
+class InvalidTestDefinitionError(Error):
+ """Raised on invalid test definition."""
+
+
+def _simpleEscapeJS(string: str) -> str:
+ return string.replace('\\', '\\\\').replace('"', '\\"')
+
+
+def _escapeJS(string: str) -> str:
+ string = _simpleEscapeJS(string)
+ # Kind of an ugly hack, for nicer failure-message output.
+ string = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', string)
+ return string
+
+
+def _expand_nonfinite(method: str, argstr: str, tail: str) -> str:
+ """
+ >>> print _expand_nonfinite('f', '<0 a>, <0 b>', ';')
+ f(a, 0);
+ f(0, b);
+ f(a, b);
+ >>> print _expand_nonfinite('f', '<0 a>, <0 b c>, <0 d>', ';')
+ f(a, 0, 0);
+ f(0, b, 0);
+ f(0, c, 0);
+ f(0, 0, d);
+ f(a, b, 0);
+ f(a, b, d);
+ f(a, 0, d);
+ f(0, b, d);
+ """
+ # argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
+ # 'invalid' is Infinity/-Infinity/NaN).
+ args = []
+ for arg in argstr.split(', '):
+ match = re.match('<(.*)>', arg)
+ if match is None:
+ raise InvalidTestDefinitionError(
+ f"Expected arg to match format '<(.*)>', but was: {arg}")
+ a = match.group(1)
+ args.append(a.split(' '))
+ calls = []
+ # Start with the valid argument list.
+ call = [args[j][0] for j in range(len(args))]
+ # For each argument alone, try setting it to all its invalid values:
+ for i in range(len(args)):
+ for a in args[i][1:]:
+ c2 = call[:]
+ c2[i] = a
+ calls.append(c2)
+ # For all combinations of >= 2 arguments, try setting them to their
+ # first invalid values. (Don't do all invalid values, because the
+ # number of combinations explodes.)
+ def f(c: List[str], start: int, depth: int) -> None:
+ for i in range(start, len(args)):
+ if len(args[i]) > 1:
+ a = args[i][1]
+ c2 = c[:]
+ c2[i] = a
+ if depth > 0:
+ calls.append(c2)
+ f(c2, i + 1, depth + 1)
+
+ f(call, 0, 0)
+
+ return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail) for c in calls)
+
+
+def _get_test_sub_dir(name: str, name_to_sub_dir: Mapping[str, str]) -> str:
+ for prefix in sorted(name_to_sub_dir.keys(), key=len, reverse=True):
+ if name.startswith(prefix):
+ return name_to_sub_dir[prefix]
+ raise InvalidTestDefinitionError(
+ 'Test "%s" has no defined target directory mapping' % name)
+
+
+def _expand_test_code(code: str) -> str:
+ code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m:
+ _expand_nonfinite(m.group(1), m.group(2), m.group(3)),
+ code) # Must come before '@assert throws'.
+
+ code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
+ r'_assertPixel(canvas, \1, \2);', code)
+
+ code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
+ r'_assertPixelApprox(canvas, \1, \2, 2);', code)
+
+ code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
+ r'_assertPixelApprox(canvas, \1, \2, \3);', code)
+
+ code = re.sub(r'@assert throws (\S+_ERR) (.*);',
+ r'assert_throws_dom("\1", function() { \2; });', code)
+
+ code = re.sub(r'@assert throws (\S+Error) (.*);',
+ r'assert_throws_js(\1, function() { \2; });', code)
+
+ code = re.sub(
+ r'@assert (.*) === (.*);', lambda m: '_assertSame(%s, %s, "%s", "%s");'
+ % (m.group(1), m.group(2), _escapeJS(m.group(1)), _escapeJS(m.group(2))
+ ), code)
+
+ code = re.sub(
+ r'@assert (.*) !== (.*);', lambda m:
+ '_assertDifferent(%s, %s, "%s", "%s");' % (m.group(1), m.group(
+ 2), _escapeJS(m.group(1)), _escapeJS(m.group(2))), code)
+
+ code = re.sub(
+ r'@assert (.*) =~ (.*);', lambda m: 'assert_regexp_match(%s, %s);' % (
+ m.group(1), m.group(2)), code)
+
+ code = re.sub(
+ r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group(
+ 1), _escapeJS(m.group(1))), code)
+
+ code = re.sub(r' @moz-todo', '', code)
+
+ code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
+
+ assert ('@' not in code)
+
+ return code
+
+
+_CANVAS_SIZE_REGEX = re.compile(r'(?P<width>.*), (?P<height>.*)',
+ re.MULTILINE | re.DOTALL)
+
+
+def _get_canvas_size(test: Mapping[str, str]):
+ size = test.get('size', '100, 50')
+ match = _CANVAS_SIZE_REGEX.match(size)
+ if not match:
+ raise InvalidTestDefinitionError(
+ 'Invalid canvas size "%s" in test %s. Expected a string matching '
+ 'this pattern: "%%s, %%s" %% (width, height)' %
+ (size, test['name']))
+ return match.group('width'), match.group('height')
+
+
+def _generate_test(test: Mapping[str, str], templates: Mapping[str, str],
+ sub_dir: str, test_output_dir: str, image_output_dir: str,
+ is_offscreen_canvas: bool):
+ name = test['name']
+
+ if test.get('expected', '') == 'green' and re.search(
+ r'@assert pixel .* 0,0,0,0;', test['code']):
+ print('Probable incorrect pixel test in %s' % name)
+
+ code = _expand_test_code(test['code'].strip())
+ code = textwrap.indent(code, ' ')
+
+ expectation_html = ''
+ if 'expected' in test and test['expected'] is not None:
+ expected = test['expected']
+ expected_img = None
+ if expected == 'green':
+ expected_img = '/images/green-100x50.png'
+ elif expected == 'clear':
+ expected_img = '/images/clear-100x50.png'
+ else:
+ if ';' in expected:
+ print('Found semicolon in %s' % name)
+ expected = re.sub(
+ r'^size (\d+) (\d+)',
+ r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
+ r'\ncr = cairo.Context(surface)', expected)
+
+ expected += ("\nsurface.write_to_png('%s.png')\n" %
+ os.path.join(image_output_dir, sub_dir, name))
+ eval(compile(expected, '<test %s>' % name, 'exec'), {},
+ {'cairo': cairo})
+ expected_img = '%s.png' % name
+
+ if expected_img:
+ expectation_html = (
+ '<p class="output expectedtext">Expected output:<p>'
+ '<img src="%s" class="output expected" id="expected" '
+ 'alt="">' % expected_img)
+
+ canvas = ' ' + test['canvas'] if 'canvas' in test else ''
+ width, height = _get_canvas_size(test)
+
+ notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else ''
+
+ timeout = ('\n<meta name="timeout" content="%s">' %
+ test['timeout'] if 'timeout' in test else '')
+ timeout_js = ('// META: timeout=%s\n' % test['timeout']
+ if 'timeout' in test else '')
+
+ images = ''
+ for src in test.get('images', []):
+ img_id = src.split('/')[-1]
+ if '/' not in src:
+ src = '../images/%s' % src
+ images += '<img src="%s" id="%s" class="resource">\n' % (src, img_id)
+ for src in test.get('svgimages', []):
+ img_id = src.split('/')[-1]
+ if '/' not in src:
+ src = '../images/%s' % src
+ images += ('<svg><image xlink:href="%s" id="%s" class="resource">'
+ '</svg>\n' % (src, img_id))
+ images = images.replace('../images/', '/images/')
+
+ fonts = ''
+ fonthack = ''
+ for font in test.get('fonts', []):
+ fonts += ('@font-face {\n font-family: %s;\n'
+ ' src: url("/fonts/%s.ttf");\n}\n' % (font, font))
+ # Browsers require the font to actually be used in the page.
+ if test.get('fonthack', 1):
+ fonthack += ('<span style="font-family: %s; position: '
+ 'absolute; visibility: hidden">A</span>\n' % font)
+ if fonts:
+ fonts = '<style>\n%s</style>\n' % fonts
+
+ fallback = test.get('fallback',
+ '<p class="fallback">FAIL (fallback content)</p>')
+
+ desc = test.get('desc', '')
+ escaped_desc = _simpleEscapeJS(desc)
+
+ attributes = test.get('attributes', '')
+ if attributes:
+ context_args = "'2d', %s" % attributes.strip()
+ attributes = ', ' + attributes.strip()
+ else:
+ context_args = "'2d'"
+
+ template_params = {
+ 'name': name,
+ 'desc': desc,
+ 'escaped_desc': escaped_desc,
+ 'notes': notes,
+ 'images': images,
+ 'fonts': fonts,
+ 'fonthack': fonthack,
+ 'timeout': timeout,
+ 'timeout_js': timeout_js,
+ 'canvas': canvas,
+ 'width': width,
+ 'height': height,
+ 'expected': expectation_html,
+ 'code': code,
+ 'fallback': fallback,
+ 'attributes': attributes,
+ 'context_args': context_args
+ }
+
+ test_path = os.path.join(test_output_dir, sub_dir, name)
+ if 'manual' in test:
+ test_path += '-manual'
+
+ if is_offscreen_canvas:
+ pathlib.Path(f'{test_path}.html').write_text(
+ templates['offscreen'] % template_params, 'utf-8')
+ pathlib.Path(f'{test_path}.worker.js').write_text(
+ templates['worker'] % template_params, 'utf-8')
+ else:
+ pathlib.Path(f'{test_path}.html').write_text(
+ templates['element'] % template_params, 'utf-8')
+
+
+def genTestUtils(TESTOUTPUTDIR: str, IMAGEOUTPUTDIR: str, TEMPLATEFILE: str,
+ NAME2DIRFILE: str, ISOFFSCREENCANVAS: bool) -> None:
+ # Run with --test argument to run unit tests
+ if len(sys.argv) > 1 and sys.argv[1] == '--test':
+ doctest = importlib.import_module('doctest')
+ doctest.testmod()
+ sys.exit()
+
+ templates = yaml.safe_load(pathlib.Path(TEMPLATEFILE).read_text())
+ name_to_sub_dir = yaml.safe_load(pathlib.Path(NAME2DIRFILE).read_text())
+
+ tests = []
+ test_yaml_directory = 'yaml/element'
+ if ISOFFSCREENCANVAS:
+ test_yaml_directory = 'yaml/offscreen'
+ TESTSFILES = [
+ os.path.join(test_yaml_directory, f)
+ for f in os.listdir(test_yaml_directory) if f.endswith('.yaml')
+ ]
+ for t in sum(
+ [yaml.safe_load(pathlib.Path(f).read_text()) for f in TESTSFILES], []):
+ if 'DISABLED' in t:
+ continue
+ if 'meta' in t:
+ eval(compile(t['meta'], '<meta test>', 'exec'), {},
+ {'tests': tests})
+ else:
+ tests.append(t)
+
+ # Ensure the test output directories exist.
+ testdirs = [TESTOUTPUTDIR, IMAGEOUTPUTDIR]
+ for sub_dir in set(name_to_sub_dir.values()):
+ testdirs.append('%s/%s' % (TESTOUTPUTDIR, sub_dir))
+ for d in testdirs:
+ try:
+ os.mkdir(d)
+ except FileExistsError:
+ pass # Ignore if it already exists.
+
+ used_tests = {}
+ for test in tests:
+ name = test['name']
+ print('\r(%s)' % name, ' ' * 32, '\t')
+
+ if name in used_tests:
+ print('Test %s is defined twice' % name)
+ used_tests[name] = 1
+
+ sub_dir = _get_test_sub_dir(name, name_to_sub_dir)
+ _generate_test(test, templates, sub_dir, TESTOUTPUTDIR, IMAGEOUTPUTDIR,
+ ISOFFSCREENCANVAS)
+
+ print()
diff --git a/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py b/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
new file mode 100644
index 0000000000..cf141f2f07
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
@@ -0,0 +1,535 @@
+# Current code status:
+#
+# This was originally written by Philip Taylor for use at
+# http://philip.html5.org/tests/canvas/suite/tests/
+#
+# It has been adapted for use with the Web Platform Test Suite suite at
+# https://github.com/web-platform-tests/wpt/
+#
+# The original version had a number of now-removed features (multiple versions
+# of each test case of varying verbosity, Mozilla mochitests, semi-automated
+# test harness). It also had a different directory structure.
+
+# To update or add test cases:
+#
+# * Modify the tests*.yaml files.
+# - 'name' is an arbitrary hierarchical name to help categorise tests.
+# - 'desc' is a rough description of what behaviour the test aims to test.
+# - 'code' is JavaScript code to execute, with some special commands starting
+# with '@'.
+# - 'expected' is what the final canvas output should be: a string 'green' or
+# 'clear' (100x50 images in both cases), or a string 'size 100 50' (or any
+# other size) followed by Python code using Pycairo to generate the image.
+#
+# * Run "./build.sh".
+# This requires a few Python modules which might not be ubiquitous.
+# It will usually emit some warnings, which ideally should be fixed but can
+# generally be safely ignored.
+#
+# * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
+
+from typing import Any, List, Mapping, Optional, Set, Tuple
+
+import re
+import collections
+import dataclasses
+import enum
+import importlib
+import itertools
+import jinja2
+import os
+import pathlib
+import sys
+
+try:
+ import cairocffi as cairo # type: ignore
+except ImportError:
+ import cairo
+
+try:
+ # Compatible and lots faster.
+ import syck as yaml # type: ignore
+except ImportError:
+ import yaml
+
+
+class Error(Exception):
+ """Base class for all exceptions raised by this module"""
+
+
+class InvalidTestDefinitionError(Error):
+ """Raised on invalid test definition."""
+
+
+def _doubleQuoteEscape(string: str) -> str:
+ return string.replace('\\', '\\\\').replace('"', '\\"')
+
+
+def _escapeJS(string: str) -> str:
+ string = _doubleQuoteEscape(string)
+ # Kind of an ugly hack, for nicer failure-message output.
+ string = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', string)
+ return string
+
+
+def _unroll(text: str) -> str:
+ """Unrolls text with all possible permutations of the parameter lists.
+
+ Example:
+ >>> print _unroll('f = {<a | b>: <1 | 2 | 3>};')
+ // a
+ f = {a: 1};
+ f = {a: 2};
+ f = {a: 3};
+ // b
+ f = {b: 1};
+ f = {b: 2};
+ f = {b: 3};
+ """
+ patterns = [] # type: List[Tuple[str, List[str]]]
+ while True:
+ match = re.search(r'<([^>]+)>', text)
+ if not match:
+ break
+ key = f'@unroll_pattern_{len(patterns)}'
+ values = text[match.start(1):match.end(1)]
+ text = text[:match.start(0)] + key + text[match.end(0):]
+ patterns.append((key, [value.strip() for value in values.split('|')]))
+
+ def unroll_patterns(text: str,
+ patterns: List[Tuple[str, List[str]]],
+ label: Optional[str] = None) -> List[str]:
+ if not patterns:
+ return [text]
+ patterns = patterns.copy()
+ key, values = patterns.pop(0)
+ return (['// ' + label] if label else []) + list(
+ itertools.chain.from_iterable(
+ unroll_patterns(text.replace(key, value), patterns, value)
+ for value in values))
+
+ result = '\n'.join(unroll_patterns(text, patterns))
+ return result
+
+
+def _expand_nonfinite(method: str, argstr: str, tail: str) -> str:
+ """
+ >>> print _expand_nonfinite('f', '<0 a>, <0 b>', ';')
+ f(a, 0);
+ f(0, b);
+ f(a, b);
+ >>> print _expand_nonfinite('f', '<0 a>, <0 b c>, <0 d>', ';')
+ f(a, 0, 0);
+ f(0, b, 0);
+ f(0, c, 0);
+ f(0, 0, d);
+ f(a, b, 0);
+ f(a, b, d);
+ f(a, 0, d);
+ f(0, b, d);
+ """
+ # argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
+ # 'invalid' is Infinity/-Infinity/NaN).
+ args = []
+ for arg in argstr.split(', '):
+ match = re.match('<(.*)>', arg)
+ if match is None:
+ raise InvalidTestDefinitionError(
+ f"Expected arg to match format '<(.*)>', but was: {arg}")
+ a = match.group(1)
+ args.append(a.split(' '))
+ calls = []
+ # Start with the valid argument list.
+ call = [args[j][0] for j in range(len(args))]
+ # For each argument alone, try setting it to all its invalid values:
+ for i in range(len(args)):
+ for a in args[i][1:]:
+ c2 = call[:]
+ c2[i] = a
+ calls.append(c2)
+ # For all combinations of >= 2 arguments, try setting them to their
+ # first invalid values. (Don't do all invalid values, because the
+ # number of combinations explodes.)
+ def f(c: List[str], start: int, depth: int) -> None:
+ for i in range(start, len(args)):
+ if len(args[i]) > 1:
+ a = args[i][1]
+ c2 = c[:]
+ c2[i] = a
+ if depth > 0:
+ calls.append(c2)
+ f(c2, i + 1, depth + 1)
+
+ f(call, 0, 0)
+
+ return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail) for c in calls)
+
+
+def _get_test_sub_dir(name: str, name_to_sub_dir: Mapping[str, str]) -> str:
+ for prefix in sorted(name_to_sub_dir.keys(), key=len, reverse=True):
+ if name.startswith(prefix):
+ return name_to_sub_dir[prefix]
+ raise InvalidTestDefinitionError(
+ 'Test "%s" has no defined target directory mapping' % name)
+
+
+def _remove_extra_newlines(text: str) -> str:
+ """Remove newlines if a backslash is found at end of line."""
+ # Lines ending with '\' gets their newline character removed.
+ text = re.sub(r'\\\n', '', text, flags=re.MULTILINE | re.DOTALL)
+
+ # Lines ending with '\-' gets their newline and any leading white spaces on
+ # the following line removed.
+ text = re.sub(r'\\-\n\s*', '', text, flags=re.MULTILINE | re.DOTALL)
+ return text
+
+def _expand_test_code(code: str) -> str:
+ code = _remove_extra_newlines(code)
+
+ # Unroll expressions with a cross-product-style parameter expansion.
+ code = re.sub(r'@unroll ([^;]*;)', lambda m: _unroll(m.group(1)), code)
+
+ code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m:
+ _expand_nonfinite(m.group(1), m.group(2), m.group(3)),
+ code) # Must come before '@assert throws'.
+
+ code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
+ r'_assertPixel(canvas, \1, \2);', code)
+
+ code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
+ r'_assertPixelApprox(canvas, \1, \2, 2);', code)
+
+ code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
+ r'_assertPixelApprox(canvas, \1, \2, \3);', code)
+
+ code = re.sub(r'@assert throws (\S+_ERR) (.*);',
+ r'assert_throws_dom("\1", function() { \2; });', code)
+
+ code = re.sub(r'@assert throws (\S+Error) (.*);',
+ r'assert_throws_js(\1, function() { \2; });', code)
+
+ code = re.sub(
+ r'@assert (.*) === (.*);', lambda m: '_assertSame(%s, %s, "%s", "%s");'
+ % (m.group(1), m.group(2), _escapeJS(m.group(1)), _escapeJS(m.group(2))
+ ), code)
+
+ code = re.sub(
+ r'@assert (.*) !== (.*);', lambda m:
+ '_assertDifferent(%s, %s, "%s", "%s");' % (m.group(1), m.group(
+ 2), _escapeJS(m.group(1)), _escapeJS(m.group(2))), code)
+
+ code = re.sub(
+ r'@assert (.*) =~ (.*);', lambda m: 'assert_regexp_match(%s, %s);' % (
+ m.group(1), m.group(2)), code)
+
+ code = re.sub(
+ r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group(
+ 1), _escapeJS(m.group(1))), code)
+
+ code = re.sub(r' @moz-todo', '', code)
+
+ code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
+
+ assert ('@' not in code)
+
+ return code
+
+
+class CanvasType(str, enum.Enum):
+ HTML_CANVAS = 'htmlcanvas'
+ OFFSCREEN_CANVAS = 'offscreencanvas'
+ WORKER = 'worker'
+
+
+def _get_enabled_canvas_types(test: Mapping[str, Any]) -> Set[CanvasType]:
+ return {CanvasType(t.lower()) for t in test.get('canvasType', CanvasType)}
+
+
+@dataclasses.dataclass
+class TestConfig:
+ out_dir: str
+ image_out_dir: str
+
+
+def _validate_test(test: Mapping[str, Any]):
+ if test.get('expected', '') == 'green' and re.search(
+ r'@assert pixel .* 0,0,0,0;', test['code']):
+ print('Probable incorrect pixel test in %s' % test['name'])
+
+ if 'size' in test and (not isinstance(test['size'], list)
+ or len(test['size']) != 2):
+ raise InvalidTestDefinitionError(
+ f'Invalid canvas size "{test["size"]}" in test {test["name"]}. '
+ 'Expected an array with two numbers.')
+
+ if 'test_type' in test and test['test_type'] != 'promise':
+ raise InvalidTestDefinitionError(
+ f'Test {test["name"]}\' test_type is invalid, it only accepts '
+ '"promise" now for creating promise test type in the template '
+ 'file.')
+
+ if 'reference' in test and 'html_reference' in test:
+ raise InvalidTestDefinitionError(
+ f'Test {test["name"]} is invalid, "reference" and "html_reference" '
+ 'can\'t both be specified at the same time.')
+
+
+def _render_template(jinja_env: jinja2.Environment,
+ template: jinja2.Template,
+ params: Mapping[str, Any]) -> str:
+ """Renders the specified jinja template.
+
+ The template is repetitively rendered until no more changes are observed.
+ This allows for template parameters to refer to other template parameters.
+ """
+ rendered = template.render(params)
+ previous = ''
+ while rendered != previous:
+ previous = rendered
+ template = jinja_env.from_string(rendered)
+ rendered = template.render(params)
+ return rendered
+
+
+def _render(jinja_env: jinja2.Environment, template_name: str,
+ params: Mapping[str, Any]):
+ params = dict(params)
+ params.update({
+ # Render the code on its own, as it could contain templates expanding
+ # to multuple lines. This is needed to get proper indentation of the
+ # code in the main template.
+ 'code': _render_template(jinja_env,
+ jinja_env.from_string(params['code']),
+ params)
+ })
+
+ return _render_template(jinja_env, jinja_env.get_template(template_name),
+ params)
+
+
+def _write_reference_test(jinja_env: jinja2.Environment,
+ params: Mapping[str, Any],
+ enabled_tests: Set[CanvasType],
+ canvas_path: str, offscreen_path: str):
+ if CanvasType.HTML_CANVAS in enabled_tests:
+ html_params = dict(params)
+ html_params.update({'canvas_type': CanvasType.HTML_CANVAS.value})
+ pathlib.Path(f'{canvas_path}.html').write_text(
+ _render(jinja_env, "reftest_element.html", html_params), 'utf-8')
+ if CanvasType.OFFSCREEN_CANVAS in enabled_tests:
+ offscreen_params = dict(params)
+ offscreen_params.update({
+ 'canvas_type': CanvasType.OFFSCREEN_CANVAS.value
+ })
+ pathlib.Path(f'{offscreen_path}.html').write_text(
+ _render(jinja_env, "reftest_offscreen.html", offscreen_params),
+ 'utf-8')
+ if CanvasType.WORKER in enabled_tests:
+ worker_params = dict(params)
+ worker_params.update({'canvas_type': CanvasType.WORKER.value})
+ pathlib.Path(f'{offscreen_path}.w.html').write_text(
+ _render(jinja_env, "reftest_worker.html", worker_params), 'utf-8')
+
+ js_ref = params.get('reference', '')
+ html_ref = params.get('html_reference', '')
+ ref_params = dict(params)
+ ref_params.update({
+ 'is_test_reference': True,
+ 'code': js_ref or html_ref
+ })
+ ref_template_name = 'reftest_element.html' if js_ref else 'reftest.html'
+ if CanvasType.HTML_CANVAS in enabled_tests:
+ pathlib.Path(f'{canvas_path}-expected.html').write_text(
+ _render(jinja_env, ref_template_name, ref_params), 'utf-8')
+ if {CanvasType.OFFSCREEN_CANVAS, CanvasType.WORKER} & enabled_tests:
+ pathlib.Path(f'{offscreen_path}-expected.html').write_text(
+ _render(jinja_env, ref_template_name, ref_params), 'utf-8')
+
+
+def _write_testharness_test(jinja_env: jinja2.Environment,
+ params: Mapping[str, Any],
+ enabled_tests: Set[CanvasType],
+ canvas_path: str,
+ offscreen_path: str):
+ # Create test cases for canvas and offscreencanvas.
+ if CanvasType.HTML_CANVAS in enabled_tests:
+ html_params = dict(params)
+ html_params.update({'canvas_type': CanvasType.HTML_CANVAS.value})
+ pathlib.Path(f'{canvas_path}.html').write_text(
+ _render(jinja_env, "testharness_element.html", html_params),
+ 'utf-8')
+
+ if CanvasType.OFFSCREEN_CANVAS in enabled_tests:
+ offscreen_params = dict(params)
+ offscreen_params.update({
+ 'canvas_type': CanvasType.OFFSCREEN_CANVAS.value
+ })
+ pathlib.Path(f'{offscreen_path}.html').write_text(
+ _render(jinja_env, "testharness_offscreen.html", offscreen_params),
+ 'utf-8')
+
+ if CanvasType.WORKER in enabled_tests:
+ worker_params = dict(params)
+ worker_params.update({'canvas_type': CanvasType.WORKER.value})
+ pathlib.Path(f'{offscreen_path}.worker.js').write_text(
+ _render(jinja_env, "testharness_worker.js", worker_params),
+ 'utf-8')
+
+
+def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment,
+ sub_dir: str, enabled_tests: Set[CanvasType],
+ html_canvas_cfg: TestConfig,
+ offscreen_canvas_cfg: TestConfig) -> None:
+ _validate_test(test)
+
+ name = test['name']
+
+ expected_img = None
+ if 'expected' in test and test['expected'] is not None:
+ expected = test['expected']
+ if expected == 'green':
+ expected_img = '/images/green-100x50.png'
+ elif expected == 'clear':
+ expected_img = '/images/clear-100x50.png'
+ else:
+ if ';' in expected:
+ print('Found semicolon in %s' % name)
+ expected = re.sub(
+ r'^size (\d+) (\d+)',
+ r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
+ r'\ncr = cairo.Context(surface)', expected)
+
+ if CanvasType.HTML_CANVAS in enabled_tests:
+ expected_canvas = (
+ expected + "\nsurface.write_to_png('%s.png')\n" %
+ os.path.join(html_canvas_cfg.image_out_dir, sub_dir, name))
+ eval(compile(expected_canvas, '<test %s>' % name, 'exec'), {},
+ {'cairo': cairo})
+
+ if {CanvasType.OFFSCREEN_CANVAS, CanvasType.WORKER} & enabled_tests:
+ expected_offscreen = (
+ expected +
+ "\nsurface.write_to_png('%s.png')\n" % os.path.join(
+ offscreen_canvas_cfg.image_out_dir, sub_dir, name))
+ eval(compile(expected_offscreen, '<test %s>' % name, 'exec'),
+ {}, {'cairo': cairo})
+
+ expected_img = '%s.png' % name
+
+ # Defaults:
+ params = {
+ 'desc': '',
+ 'size': [100, 50],
+ }
+
+ params.update(test)
+ params.update({
+ 'code': _expand_test_code(test['code']),
+ 'expected_img': expected_img
+ })
+
+ canvas_path = os.path.join(html_canvas_cfg.out_dir, sub_dir, name)
+ offscreen_path = os.path.join(offscreen_canvas_cfg.out_dir, sub_dir, name)
+ if 'manual' in test:
+ canvas_path += '-manual'
+ offscreen_path += '-manual'
+
+ if 'reference' in test or 'html_reference' in test:
+ _write_reference_test(jinja_env, params, enabled_tests,
+ canvas_path, offscreen_path)
+ else:
+ _write_testharness_test(jinja_env, params, enabled_tests, canvas_path,
+ offscreen_path)
+
+
+def genTestUtils_union(NAME2DIRFILE: str) -> None:
+ CANVASOUTPUTDIR = '../element'
+ CANVASIMAGEOUTPUTDIR = '../element'
+ OFFSCREENCANVASOUTPUTDIR = '../offscreen'
+ OFFSCREENCANVASIMAGEOUTPUTDIR = '../offscreen'
+
+ jinja_env = jinja2.Environment(
+ loader=jinja2.PackageLoader("gentestutilsunion"),
+ keep_trailing_newline=True,
+ trim_blocks=True,
+ lstrip_blocks=True)
+
+ jinja_env.filters['double_quote_escape'] = _doubleQuoteEscape
+
+ # Run with --test argument to run unit tests.
+ if len(sys.argv) > 1 and sys.argv[1] == '--test':
+ doctest = importlib.import_module('doctest')
+ doctest.testmod()
+ sys.exit()
+
+ name_to_sub_dir = yaml.safe_load(pathlib.Path(NAME2DIRFILE).read_text())
+
+ tests = []
+ test_yaml_directory = 'yaml-new'
+ TESTSFILES = [
+ os.path.join(test_yaml_directory, f)
+ for f in os.listdir(test_yaml_directory) if f.endswith('.yaml')
+ ]
+ for t in sum(
+ [yaml.safe_load(pathlib.Path(f).read_text()) for f in TESTSFILES], []):
+ if 'DISABLED' in t:
+ continue
+ if 'meta' in t:
+ eval(compile(t['meta'], '<meta test>', 'exec'), {},
+ {'tests': tests})
+ else:
+ tests.append(t)
+
+ # Ensure the test output directories exist.
+ testdirs = [
+ CANVASOUTPUTDIR, OFFSCREENCANVASOUTPUTDIR, CANVASIMAGEOUTPUTDIR,
+ OFFSCREENCANVASIMAGEOUTPUTDIR
+ ]
+ for sub_dir in set(name_to_sub_dir.values()):
+ testdirs.append('%s/%s' % (CANVASOUTPUTDIR, sub_dir))
+ testdirs.append('%s/%s' % (OFFSCREENCANVASOUTPUTDIR, sub_dir))
+ for d in testdirs:
+ try:
+ os.mkdir(d)
+ except FileExistsError:
+ pass # Ignore if it already exists,
+
+ used_tests = collections.defaultdict(set)
+ for original_test in tests:
+ variants = original_test.get('variants', {'': dict()})
+ for variant_name, variant_params in variants.items():
+ test = original_test.copy()
+ if variant_name or variant_params:
+ # Append variant name. Variant names starting with '_' are
+ # not appended, which is useful to create variants with the same
+ # name in different folders (element vs. offscreen).
+ if not variant_name.startswith('_'):
+ test['name'] += '.' + variant_name
+ test.update(variant_params)
+
+ name = test['name']
+ print('\r(%s)' % name, ' ' * 32, '\t')
+
+ enabled_canvas_types = _get_enabled_canvas_types(test)
+
+ already_tested = used_tests[name].intersection(
+ enabled_canvas_types)
+ if already_tested:
+ raise InvalidTestDefinitionError(
+ f'Test {name} is defined twice for types {already_tested}')
+ used_tests[name].update(enabled_canvas_types)
+
+ sub_dir = _get_test_sub_dir(name, name_to_sub_dir)
+ _generate_test(
+ test,
+ jinja_env,
+ sub_dir,
+ enabled_canvas_types,
+ html_canvas_cfg=TestConfig(
+ out_dir=CANVASOUTPUTDIR,
+ image_out_dir=CANVASIMAGEOUTPUTDIR),
+ offscreen_canvas_cfg=TestConfig(
+ out_dir=OFFSCREENCANVASOUTPUTDIR,
+ image_out_dir=OFFSCREENCANVASIMAGEOUTPUTDIR))
+
+ print()
diff --git a/testing/web-platform/tests/html/canvas/tools/name2dir-canvas.yaml b/testing/web-platform/tests/html/canvas/tools/name2dir-canvas.yaml
new file mode 100644
index 0000000000..1e0caff5b9
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/name2dir-canvas.yaml
@@ -0,0 +1,26 @@
+2d.transformation: "transformations"
+2d.color.space: 'wide-gamut-canvas'
+2d.composite: "compositing"
+2d.coordinatespace: "conformance-requirements"
+2d.missingargs: "conformance-requirements"
+2d.type.delete: "conformance-requirements"
+2d.voidreturn: "conformance-requirements"
+2d.drawImage: "drawing-images-to-the-canvas"
+2d.clearRect: "drawing-rectangles-to-the-canvas"
+2d.fillRect: "drawing-rectangles-to-the-canvas"
+2d.strokeRect: "drawing-rectangles-to-the-canvas"
+2d.text: "text"
+2d.fillStyle: "fill-and-stroke-styles"
+2d.gradient: "fill-and-stroke-styles"
+2d.pattern: "fill-and-stroke-styles"
+2d.strokeStyle: "fill-and-stroke-styles"
+2d.path: "path-objects"
+2d.imageData: "pixel-manipulation"
+2d.reset: "reset"
+2d.shadow: "shadows"
+2d.filter: "filters"
+2d.state: "the-canvas-state"
+2d.scrollPathIntoView: "scroll"
+2d.video: "video"
+2d.canvas.host: "canvas-host"
+2d.canvas.context: "canvas-context"
diff --git a/testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml b/testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml
new file mode 100644
index 0000000000..c52acb793b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml
@@ -0,0 +1,22 @@
+2d.state: "the-canvas-state"
+2d.transformation: "transformations"
+2d.color.space: "wide-gamut-canvas"
+2d.composite: "compositing"
+2d.fillStyle: "fill-and-stroke-styles"
+2d.gradient: "fill-and-stroke-styles"
+2d.pattern: "fill-and-stroke-styles"
+2d.strokeStyle: "fill-and-stroke-styles"
+2d.shadow: "shadows"
+2d.filter: "filters"
+2d.clearRect: "drawing-rectangles-to-the-canvas"
+2d.fillRect: "drawing-rectangles-to-the-canvas"
+2d.strokeRect: "drawing-rectangles-to-the-canvas"
+2d.drawImage: "drawing-images-to-the-canvas"
+2d.imageData: "pixel-manipulation"
+2d.path: "path-objects"
+2d.text: "text"
+2d.coordinatespace: "conformance-requirements"
+2d.missingargs: "conformance-requirements"
+2d.voidreturn: "conformance-requirements"
+2d.canvas.host: "canvas-host"
+2d.canvas.context: "canvas-context" \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/tools/name2dir.yaml b/testing/web-platform/tests/html/canvas/tools/name2dir.yaml
new file mode 100644
index 0000000000..ae69c15378
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/name2dir.yaml
@@ -0,0 +1,25 @@
+2d.transformation: "transformations"
+2d.color.space: 'wide-gamut-canvas'
+2d.composite: "compositing"
+2d.conformance.requirements: "conformance-requirements"
+2d.drawImage: "drawing-images-to-the-canvas"
+2d.clearRect: "drawing-rectangles-to-the-canvas"
+2d.fillRect: "drawing-rectangles-to-the-canvas"
+2d.strokeRect: "drawing-rectangles-to-the-canvas"
+2d.text: "text"
+2d.fillStyle: "fill-and-stroke-styles"
+2d.gradient: "fill-and-stroke-styles"
+2d.pattern: "fill-and-stroke-styles"
+2d.strokeStyle: "fill-and-stroke-styles"
+2d.line: "line-styles"
+2d.path: "path-objects"
+2d.imageData: "pixel-manipulation"
+2d.reset: "reset"
+2d.shadow: "shadows"
+2d.filter: "filters"
+2d.layer: "layers"
+2d.state: "the-canvas-state"
+2d.scrollPathIntoView: "scroll"
+2d.video: "video"
+2d.canvas.host: "canvas-host"
+2d.canvas.context: "canvas-context"
diff --git a/testing/web-platform/tests/html/canvas/tools/templates.yaml b/testing/web-platform/tests/html/canvas/tools/templates.yaml
new file mode 100644
index 0000000000..0806872cbd
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates.yaml
@@ -0,0 +1,80 @@
+offscreen: |
+ <!DOCTYPE html>
+ <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+ <title>OffscreenCanvas test: %(name)s</title>%(timeout)s
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/html/canvas/resources/canvas-tests.js"></script>
+
+ <h1>%(name)s</h1>
+ <p class="desc">%(desc)s</p>
+
+ %(notes)s
+ <script>
+ var t = async_test("%(escaped_desc)s");
+ var t_pass = t.done.bind(t);
+ var t_fail = t.step_func(function(reason) {
+ throw reason;
+ });
+ t.step(function() {
+
+ var canvas = new OffscreenCanvas(%(width)s, %(height)s);
+ var ctx = canvas.getContext(%(context_args)s);
+
+ %(code)s
+
+ });
+ </script>
+
+
+worker: |
+ %(timeout_js)s// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+ // OffscreenCanvas test in a worker:%(name)s
+ // Description:%(desc)s
+ // Note:%(notes)s
+
+ importScripts("/resources/testharness.js");
+ importScripts("/html/canvas/resources/canvas-tests.js");
+
+ var t = async_test("%(escaped_desc)s");
+ var t_pass = t.done.bind(t);
+ var t_fail = t.step_func(function(reason) {
+ throw reason;
+ });
+ t.step(function() {
+
+ var canvas = new OffscreenCanvas(%(width)s, %(height)s);
+ var ctx = canvas.getContext(%(context_args)s);
+
+ %(code)s
+ });
+ done();
+
+
+element: |
+ <!DOCTYPE html>
+ <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+ <title>Canvas test: %(name)s</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/html/canvas/resources/canvas-tests.js"></script>
+ <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+ %(fonts)s<body class="show_output">
+
+ <h1>%(name)s</h1>
+ <p class="desc">%(desc)s</p>
+
+ %(notes)s
+ %(fonthack)s<p class="output">Actual output:</p>
+ <canvas id="c" class="output" width="%(width)s" height="%(height)s"%(canvas)s>%(fallback)s</canvas>
+ %(expected)s
+ <ul id="d"></ul>
+ <script>
+ var t = async_test("%(escaped_desc)s");
+ _addTest(function(canvas, ctx) {
+
+ %(code)s
+
+ }%(attributes)s);
+ </script>
+ %(images)s
diff --git a/testing/web-platform/tests/html/canvas/tools/templates/reftest.html b/testing/web-platform/tests/html/canvas/tools/templates/reftest.html
new file mode 100644
index 0000000000..4c9affbbbb
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates/reftest.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: {{ name }}</title>
+<h1>{{ name }}</h1>
+<p class="desc">{{ desc }}</p>
+{% if notes %}<p class="notes">{{ notes }}{% endif %}
+
+{{ code | trim }}
+{% for image in images %}
+<img src="/images/{{ image }}" id="{{ image }}" class="resource">
+{% endfor -%}
+{% for svgimage in svgimages %}
+<svg><image xlink:href="/images/{{ svgimage }}" id="{{ svgimage }}" class="resource"></svg>
+{% endfor -%}
diff --git a/testing/web-platform/tests/html/canvas/tools/templates/reftest_element.html b/testing/web-platform/tests/html/canvas/tools/templates/reftest_element.html
new file mode 100644
index 0000000000..6684e9c615
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates/reftest_element.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+{% if test_type == 'promise' %}<html class="reftest-wait">
+{% endif %}
+{% if not is_test_reference %}
+<link rel="match" href="{{ name }}-expected.html">
+{% if fuzzy %}<meta name=fuzzy content="{{ fuzzy }}">
+{% endif %}
+{% endif %}
+{% if timeout %}<meta name="timeout" content="{{ timeout }}">
+{% endif %}
+<title>Canvas test: {{ name }}</title>
+<h1>{{ name }}</h1>
+<p class="desc">{{ desc }}</p>
+{% if notes %}<p class="notes">{{ notes }}{% endif %}
+<canvas id="canvas" width="{{ size[0] }}" height="{{ size[1] }}"{{ canvas }}>
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script{% if test_type == 'promise' %} type="module"{% endif %}>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d'{% if attributes %}, {{ attributes }}{% endif %});
+
+ {{ code | trim | indent(2) }}
+ {% if test_type == 'promise' %}
+ document.documentElement.classList.remove("reftest-wait");
+ {% endif %}
+</script>
+{% for image in images %}
+<img src="/images/{{ image }}" id="{{ image }}" class="resource">
+{% endfor -%}
+{% for svgimage in svgimages %}
+<svg><image xlink:href="/images/{{ svgimage }}" id="{{ svgimage }}" class="resource"></svg>
+{% endfor -%}
+{% if test_type == 'promise' %}</html>{% endif %}
diff --git a/testing/web-platform/tests/html/canvas/tools/templates/reftest_offscreen.html b/testing/web-platform/tests/html/canvas/tools/templates/reftest_offscreen.html
new file mode 100644
index 0000000000..1d0d93dfa1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates/reftest_offscreen.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+{% if test_type == 'promise' %}<html class="reftest-wait">
+{% endif %}
+<link rel="match" href="{{ name }}-expected.html">
+{% if fuzzy %}<meta name=fuzzy content="{{ fuzzy }}">
+{% endif %}
+{% if timeout %}<meta name="timeout" content="{{ timeout }}">
+{% endif %}
+<title>Canvas test: {{ name }}</title>
+<h1>{{ name }}</h1>
+<p class="desc">{{ desc }}</p>
+{% if notes %}<p class="notes">{{ notes }}{% endif %}
+<canvas id="canvas" width="{{ size[0] }}" height="{{ size[1] }}"{{ canvas }}>
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script{% if test_type == 'promise' %} type="module"{% endif %}>
+ const canvas = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
+ const ctx = canvas.getContext('2d'{% if attributes %}, {{ attributes }}{% endif %});
+
+ {{ code | trim | indent(2) }}
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d'{% if attributes %}, {{ attributes }}{% endif %}).drawImage(canvas, 0, 0);
+ {% if test_type == 'promise' %}
+ document.documentElement.classList.remove("reftest-wait");
+ {% endif %}
+</script>
+{% if test_type == 'promise' %}</html>{% endif %}
diff --git a/testing/web-platform/tests/html/canvas/tools/templates/reftest_worker.html b/testing/web-platform/tests/html/canvas/tools/templates/reftest_worker.html
new file mode 100644
index 0000000000..e636d3634b
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates/reftest_worker.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="{{ name }}-expected.html">
+{% if fuzzy %}<meta name=fuzzy content="{{ fuzzy }}">
+{% endif %}
+{% if timeout %}<meta name="timeout" content="{{ timeout }}">
+{% endif %}
+<title>Canvas test: {{ name }}</title>
+<h1>{{ name }}</h1>
+<p class="desc">{{ desc }}</p>
+{% if notes %}<p class="notes">{{ notes }}{% endif %}
+<canvas id="canvas" width="{{ size[0] }}" height="{{ size[1] }}"{{ canvas }}>
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = {% if test_type == 'promise' %}async {% endif %}function(e) {
+ const canvas = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
+ const ctx = canvas.getContext('2d'{% if attributes %}, {{ attributes }}{% endif %});
+
+ {{ code | trim | indent(4) }}
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d'{% if attributes %}, {{ attributes }}{% endif %});
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/canvas/tools/templates/testharness_element.html b/testing/web-platform/tests/html/canvas/tools/templates/testharness_element.html
new file mode 100644
index 0000000000..56cde7936a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates/testharness_element.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: {{ name }}</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+{% if fonts %}
+<style>
+{% for font in fonts %}
+@font-face {
+ font-family: {{ font }};
+ src: url("/fonts/{{ font }}.ttf");
+}
+{% endfor %}
+</style>
+{% endif %}
+<body class="show_output">
+
+<h1>{{ name }}</h1>
+<p class="desc">{{ desc }}</p>
+
+{% if notes %}<p class="notes">{{ notes }}
+{% else %}
+
+{% endif %}
+{% if fonts and not font_unused_in_dom %}
+{% for font in fonts %}
+<span style="font-family: {{ font }}; position: absolute; visibility: hidden">A</span>
+{% endfor %}
+{% endif %}
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="{{ size[0] }}" height="{{ size[1] }}"
+ {{- canvas}}><p class="fallback">FAIL (fallback content)</p></canvas>
+{% if expected_img %}
+<p class="output expectedtext">Expected output:<p><img src="{{ expected_img }}" class="output expected" id="expected" alt="">
+{%- endif +%}
+<ul id="d"></ul>
+<script>
+
+{#- Promise vs. async test header: +#}
+{% if test_type == 'promise' %}
+promise_test(async t => {
+
+ var canvas = document.getElementById('c');
+ var ctx = canvas.getContext('2d'{% if attributes %}, {{ attributes }}{% endif %});
+{% else %}
+var t = async_test("{{ desc | double_quote_escape }}");
+_addTest(function(canvas, ctx) {
+{% endif %}
+
+ {# Test body: #}
+ {{ code | trim | indent(2) }}
+
+{# Promise vs. async test footer: #}
+{% if test_type == 'promise' %}
+}, "{{ desc }}");
+{% else %}
+}{% if attributes %}, {{ attributes }}{% endif %});
+{% endif -%}
+
+</script>
+{% for image in images %}
+<img src="/images/{{ image }}" id="{{ image }}" class="resource">
+{% endfor -%}
+{% for svgimage in svgimages %}
+<svg><image xlink:href="/images/{{ svgimage }}" id="{{ svgimage }}" class="resource"></svg>
+{% endfor +%}
diff --git a/testing/web-platform/tests/html/canvas/tools/templates/testharness_offscreen.html b/testing/web-platform/tests/html/canvas/tools/templates/testharness_offscreen.html
new file mode 100644
index 0000000000..8ebbff77a6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates/testharness_offscreen.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: {{ name }}</title>
+{% if timeout %}<meta name="timeout" content="{{ timeout }}">{% endif %}
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>{{ name }}</h1>
+<p class="desc">{{ desc }}</p>
+
+{% if notes %}<p class="notes">{{ notes }}{% endif +%}
+<script>
+
+{#- Promise vs. async test header: +#}
+{% if test_type == 'promise' %}
+promise_test(async t => {
+{% else %}
+var t = async_test("{{ desc | double_quote_escape }}");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+{% endif %}
+
+{# Test body: #}
+ var canvas = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
+ var ctx = canvas.getContext('2d'{% if attributes %}, {{ attributes }}{% endif %});
+
+ {{ code | trim | indent(2)}}
+
+{#- Promise vs. async test footer: +#}
+{% if test_type == 'promise' %}
+
+}, "{{ desc }}");
+{% else %}
+ t.done();
+
+});
+{% endif %}
+</script>
+{% for svgimage in svgimages %}
+<svg><image xlink:href="/images/{{ svgimage }}" id="{{ svgimage }}" class="resource"></svg>
+{% endfor %}
diff --git a/testing/web-platform/tests/html/canvas/tools/templates/testharness_worker.js b/testing/web-platform/tests/html/canvas/tools/templates/testharness_worker.js
new file mode 100644
index 0000000000..f1f04e7bb6
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/templates/testharness_worker.js
@@ -0,0 +1,35 @@
+{% if timeout %}// META: timeout={{ timeout }}{% endif %}
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:{{ name }}
+// Description:{{ desc }}
+// Note:{% if notes %}<p class="notes">{{ notes }}{% endif +%}
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+{# Promise vs. async test header: #}
+{% if test_type == 'promise' %}
+promise_test(async t => {
+{% else %}
+var t = async_test("{{ desc | double_quote_escape }}");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+ throw reason;
+});
+t.step(function() {
+{% endif %}
+
+{# Test body: #}
+ var canvas = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
+ var ctx = canvas.getContext('2d'{% if attributes %}, {{ attributes }}{% endif %});
+
+ {{ code | trim | indent(2)}}
+ t.done();
+
+{#- Promise vs. async test footer: +#}
+{% if test_type == 'promise' %}
+}, "{{ desc }}");
+{% else %}
+});
+{% endif %}
+done();
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml
new file mode 100644
index 0000000000..39556caf0a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/color_space.yaml
@@ -0,0 +1,319 @@
+- name: 2d.color.space.p3.to.p3
+ desc: test getImageData with display-p3 and uint8 from display p3 uint8 canvas
+ attributes: '{colorSpace: "display-p3"}'
+ code: |
+ var color_style = 'rgb(50, 100, 150)';
+ // [0.24304, 0.38818, 0.57227, 1.0] * 255 = [62, 99, 146, 255]
+ var pixel_expected = [62, 99, 146, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "display-p3", storageFormat: "uint8"}).data;
+ @assert pixel.length === pixel_expected.length;
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+
+- name: 2d.color.space.p3.to.srgb
+ desc: test getImageData with srsb and uint8 from display p3 uint8 canvas
+ attributes: '{colorSpace: "display-p3"}'
+ code: |
+ var color_style = 'rgb(50, 100, 150)';
+ var pixel_expected = [50, 100, 150, 255];
+ var epsilon = 2;
+ ctx.fillStyle = color_style;
+ ctx.fillRect(0, 0, 10, 10);
+
+ var pixel = ctx.getImageData(5, 5, 1, 1, {colorSpace: "srgb", storageFormat: "uint8"}).data;
+ @assert pixel.length === pixel_expected.length;
+ assert_approx_equals(pixel[0], pixel_expected[0], 2);
+ assert_approx_equals(pixel[1], pixel_expected[1], 2);
+ assert_approx_equals(pixel[2], pixel_expected[2], 2);
+ assert_approx_equals(pixel[3], pixel_expected[3], 2);
+
+- name: 2d.color.space.p3.toBlob.p3.canvas
+ desc: test if toblob returns p3 data from p3 color space canvas
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+
+ canvas.toBlob(function(blob) {
+ var urlCreator = window.URL || window.webkitURL;
+ image.src = urlCreator.createObjectURL(blob);
+ }, 'image/png', 1);
+
+- name: 2d.color.space.p3.toDataURL.p3.canvas
+ desc: test if toDataURL returns p3 data from canvas with p3 color space
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL();
+
+- name: 2d.color.space.p3.toDataURL.jpeg.p3.canvas
+ desc: test if toDataURL('image/jpeg') returns p3 data from canvas with p3 color space
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = "rgba(155, 27, 27, 1)";
+ ctx.fillRect(0, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 155, 27, 0)";
+ ctx.fillRect(1, 0, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 155, 0.5)";
+ ctx.fillRect(0, 1, 1, 1);
+ ctx.fillStyle = "rgba(27, 27, 27, 0.5)";
+ ctx.fillRect(1, 1, 1, 1);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL("image/jpeg");
+
+- name: 2d.color.space.p3.toBlob.with.putImageData
+ desc: Use putImageData to put some p3 data in canvas and test if toBlob returns the same data
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ canvas.width = 2;
+ canvas.height = 2;
+
+ // Create an ImageData using createImageData and populate its data array.
+ var image_data = ctx.createImageData(canvas.width, canvas.height, {colorSpace: "display-p3"});
+ var color_data = [[255, 100, 150, 1.0], [255, 100, 150, 0.5],
+ [255, 100, 150, 0.5], [255, 100, 150, 0]];
+ var data = image_data.data;
+ for (var i = 0; i < data.length / 4; ++i) {
+ data[4*i + 0] = color_data[i][0];
+ data[4*i + 1] = color_data[i][1];
+ data[4*i + 2] = color_data[i][2];
+ data[4*i + 3] = color_data[i][3];
+ }
+ ctx.putImageData(image_data, 0, 0);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ canvas.toBlob(function(blob) {
+ var urlCreator = window.URL || window.webkitURL;
+ image.src = urlCreator.createObjectURL(blob);
+ }, 'image/png', 1);
+
+- name: 2d.color.space.p3.toDataURL.with.putImageData
+ desc: Use putImageData to put some p3 data in canvas and test if toDataURL returns the same data
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ canvas.width = 2;
+ canvas.height = 2;
+
+ // Create an ImageData using createImageData and populate its data array.
+ var image_data = ctx.createImageData(canvas.width, canvas.height, {colorSpace: "display-p3"});
+ var color_data = [[255, 100, 150, 1.0], [255, 100, 150, 0.5],
+ [255, 100, 150, 0.5], [255, 100, 150, 0]];
+ var data = image_data.data;
+ for (var i = 0; i < data.length / 4; ++i) {
+ data[4*i + 0] = color_data[i][0];
+ data[4*i + 1] = color_data[i][1];
+ data[4*i + 2] = color_data[i][2];
+ data[4*i + 3] = color_data[i][3];
+ }
+ ctx.putImageData(image_data, 0, 0);
+ expectedPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+
+ var image = new Image();
+ image.onload = t.step_func_done(function() {
+ var dstCanvas = document.createElement("canvas");
+ dstCanvas.width = 2;
+ dstCanvas.height = 2;
+ var ctx = dstCanvas.getContext('2d', {colorSpace: "display-p3"});
+ ctx.drawImage(image, 0, 0);
+ var actualPixels = ctx.getImageData(0, 0, 2, 2, {colorSpace: "display-p3"}).data;
+ assert_array_approx_equals(actualPixels, expectedPixels, 2);
+ });
+ image.src = canvas.toDataURL();
+
+- name: 2d.color.space.p3.fillText
+ desc: Test if fillText can be used with a solid display-p3 color
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType: ['HTMLCanvas']
+ code: |
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.fillStyle = "#f00";
+ ctx.fillText("A", 0, 50);
+
+ ctx.fillStyle = "black";
+ ctx.fillStyle = "color(display-p3 100% 0 0)";
+ ctx.fillText("A", 50, 50);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
+
+- name: 2d.color.space.p3.strokeText
+ desc: Test if strokeText can be used with a solid display-p3 color
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.strokeStyle = "#f00";
+ ctx.lineWidth = 20;
+ ctx.strokeText("A", 0, 50);
+
+ ctx.strokeStyle = "black";
+ ctx.strokeStyle = "color(display-p3 100% 0 0)";
+ ctx.strokeText("A", 50, 50);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
+
+- name: 2d.color.space.p3.fillText.shadow
+ desc: Test if fillText can be used with a display-p3 shadow color
+ attributes: '{colorSpace: "display-p3"}'
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ deferTest();
+
+ const fullRedInP3 = [255, 0, 0, 255];
+ const sRGBRedInP3 = [234, 51, 35, 255];
+
+ canvas.width = 100;
+ canvas.height = 100;
+
+ let f = new FontFace("Ahem", "url(/fonts/Ahem.ttf)");
+ document.fonts.add(f);
+ f.load().then(function() {
+ t.step(function() {
+ ctx.font = "40px Ahem";
+
+ ctx.fillStyle = "black";
+ ctx.shadowBlur = 4;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = "#f00";
+ ctx.fillText("A", 0, 0);
+
+ ctx.shadowColor = "black";
+ ctx.shadowColor = "color(display-p3 100% 0 0)";
+ ctx.fillText("A", 50, 0);
+
+ let pixels = ctx.getImageData(0, 0, canvas.width, canvas.height, { colorSpace: "display-p3" }).data;
+ let pixelAt = function(x, y) {
+ let offset = (y * canvas.width + x) * 4;
+ return [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
+ };
+
+ assert_array_equals(pixelAt(25, 25), sRGBRedInP3);
+ assert_array_equals(pixelAt(75, 25), fullRedInP3);
+
+ t.done();
+ });
+ });
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml
new file mode 100644
index 0000000000..bd7fae1d62
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/compositing.yaml
@@ -0,0 +1,232 @@
+- name: 2d.composite.globalAlpha.range
+ code: |
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = 1.1;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = -0.1;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = 0;
+ @assert ctx.globalAlpha === 0;
+ ctx.globalAlpha = 1;
+ @assert ctx.globalAlpha === 1;
+
+- name: 2d.composite.globalAlpha.invalid
+ code: |
+ ctx.globalAlpha = 0.5;
+ // This may not set it to exactly 0.5 if it is rounded/quantised, so
+ // remember for future comparisons.
+ var a = ctx.globalAlpha;
+ ctx.globalAlpha = Infinity;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = -Infinity;
+ @assert ctx.globalAlpha === a;
+ ctx.globalAlpha = NaN;
+ @assert ctx.globalAlpha === a;
+
+- name: 2d.composite.globalAlpha.default
+ code: |
+ @assert ctx.globalAlpha === 1.0;
+
+- name: 2d.composite.globalAlpha.fill
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvas
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.drawImage(canvas2, 0, 0);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvaspattern
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(canvas2, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvascopy
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.globalCompositeOperation = 'copy'
+ ctx.globalAlpha = 0.51;
+ ctx.drawImage(canvas2, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,130;
+ expected: green
+
+
+- name: 2d.composite.operation.get
+ code: |
+ var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
+ 'destination-atop', 'destination-in', 'destination-out', 'destination-over',
+ 'lighter', 'copy', 'xor'];
+ for (var i = 0; i < modes.length; ++i)
+ {
+ ctx.globalCompositeOperation = modes[i];
+ @assert ctx.globalCompositeOperation === modes[i];
+ }
+
+- name: 2d.composite.operation.unrecognised
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'nonexistent';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.darker
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'darker';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.over
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'over';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.clear
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'clear';
+ @assert ctx.globalCompositeOperation === 'clear';
+
+- name: 2d.composite.operation.highlight
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'highlight';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.nullsuffix
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'source-over\0';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.casesensitive
+ code: |
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'Source-over';
+ @assert ctx.globalCompositeOperation === 'xor';
+
+- name: 2d.composite.operation.default
+ code: |
+ @assert ctx.globalCompositeOperation === 'source-over';
+
+
+- name: 2d.composite.globalAlpha.image
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvas
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+
+- name: 2d.composite.globalAlpha.imagepattern
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+ expected: green
+
+- name: 2d.composite.globalAlpha.canvaspattern
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = ctx.createPattern(offscreenCanvas2, 'no-repeat');
+ // Avoiding any potential alpha = 0 optimisations.
+ ctx.globalAlpha = 0.01;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 2,253,0,255;
+
+- name: 2d.composite.globalAlpha.canvascopy
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy'
+ ctx.globalAlpha = 0.51;
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,130;
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml
new file mode 100644
index 0000000000..3483d115f4
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/conformance_requirements.yaml
@@ -0,0 +1,178 @@
+- name: 2d.conformance.requirements.delete
+ desc: window.CanvasRenderingContext2D is Configurable
+ notes: &bindings Defined in "Web IDL" (draft)
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert window.CanvasRenderingContext2D !== undefined;
+ @assert delete window.CanvasRenderingContext2D === true;
+ @assert window.CanvasRenderingContext2D === undefined;
+
+- name: 2d.conformance.requirements.basics
+ desc: void methods return undefined
+ notes: *bindings
+ code: |
+ @assert ctx.save() === undefined;
+ @assert ctx.restore() === undefined;
+ @assert ctx.scale(1, 1) === undefined;
+ @assert ctx.rotate(0) === undefined;
+ @assert ctx.translate(0, 0) === undefined;
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ @assert ctx.transform(1, 0, 0, 1, 0, 0) === undefined;
+ }
+ if (ctx.setTransform) {
+ @assert ctx.setTransform(1, 0, 0, 1, 0, 0) === undefined;
+ @assert ctx.setTransform() === undefined;
+ }
+ @assert ctx.clearRect(0, 0, 0, 0) === undefined;
+ @assert ctx.fillRect(0, 0, 0, 0) === undefined;
+ @assert ctx.strokeRect(0, 0, 0, 0) === undefined;
+ @assert ctx.beginPath() === undefined;
+ @assert ctx.closePath() === undefined;
+ @assert ctx.moveTo(0, 0) === undefined;
+ @assert ctx.lineTo(0, 0) === undefined;
+ @assert ctx.quadraticCurveTo(0, 0, 0, 0) === undefined;
+ @assert ctx.bezierCurveTo(0, 0, 0, 0, 0, 0) === undefined;
+ @assert ctx.arcTo(0, 0, 0, 0, 1) === undefined;
+ @assert ctx.rect(0, 0, 0, 0) === undefined;
+ @assert ctx.arc(0, 0, 1, 0, 0, true) === undefined;
+ @assert ctx.fill() === undefined;
+ @assert ctx.stroke() === undefined;
+ @assert ctx.clip() === undefined;
+ if (ctx.fillText) {
+ @assert ctx.fillText('test', 0, 0) === undefined;
+ @assert ctx.strokeText('test', 0, 0) === undefined;
+ }
+ if (ctx.putImageData) {
+ @assert ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0) === undefined;
+ }
+ @assert ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0) === undefined;
+ @assert ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white') === undefined;
+
+- name: 2d.conformance.requirements.missingargs
+ desc: Missing arguments cause TypeError
+ code: |
+ @assert throws TypeError ctx.scale();
+ @assert throws TypeError ctx.scale(1);
+ @assert throws TypeError ctx.rotate();
+ @assert throws TypeError ctx.translate();
+ @assert throws TypeError ctx.translate(0);
+ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported)
+ @assert throws TypeError ctx.transform();
+ @assert throws TypeError ctx.transform(1);
+ @assert throws TypeError ctx.transform(1, 0);
+ @assert throws TypeError ctx.transform(1, 0, 0);
+ @assert throws TypeError ctx.transform(1, 0, 0, 1);
+ @assert throws TypeError ctx.transform(1, 0, 0, 1, 0);
+ }
+ if (ctx.setTransform) {
+ @assert throws TypeError ctx.setTransform(1);
+ @assert throws TypeError ctx.setTransform(1, 0);
+ @assert throws TypeError ctx.setTransform(1, 0, 0);
+ @assert throws TypeError ctx.setTransform(1, 0, 0, 1);
+ @assert throws TypeError ctx.setTransform(1, 0, 0, 1, 0);
+ }
+ @assert throws TypeError ctx.createLinearGradient();
+ @assert throws TypeError ctx.createLinearGradient(0);
+ @assert throws TypeError ctx.createLinearGradient(0, 0);
+ @assert throws TypeError ctx.createLinearGradient(0, 0, 1);
+ @assert throws TypeError ctx.createRadialGradient();
+ @assert throws TypeError ctx.createRadialGradient(0);
+ @assert throws TypeError ctx.createRadialGradient(0, 0);
+ @assert throws TypeError ctx.createRadialGradient(0, 0, 1);
+ @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0);
+ @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0, 0);
+ @assert throws TypeError ctx.createPattern(canvas);
+ @assert throws TypeError ctx.clearRect();
+ @assert throws TypeError ctx.clearRect(0);
+ @assert throws TypeError ctx.clearRect(0, 0);
+ @assert throws TypeError ctx.clearRect(0, 0, 0);
+ @assert throws TypeError ctx.fillRect();
+ @assert throws TypeError ctx.fillRect(0);
+ @assert throws TypeError ctx.fillRect(0, 0);
+ @assert throws TypeError ctx.fillRect(0, 0, 0);
+ @assert throws TypeError ctx.strokeRect();
+ @assert throws TypeError ctx.strokeRect(0);
+ @assert throws TypeError ctx.strokeRect(0, 0);
+ @assert throws TypeError ctx.strokeRect(0, 0, 0);
+ @assert throws TypeError ctx.moveTo();
+ @assert throws TypeError ctx.moveTo(0);
+ @assert throws TypeError ctx.lineTo();
+ @assert throws TypeError ctx.lineTo(0);
+ @assert throws TypeError ctx.quadraticCurveTo();
+ @assert throws TypeError ctx.quadraticCurveTo(0);
+ @assert throws TypeError ctx.quadraticCurveTo(0, 0);
+ @assert throws TypeError ctx.quadraticCurveTo(0, 0, 0);
+ @assert throws TypeError ctx.bezierCurveTo();
+ @assert throws TypeError ctx.bezierCurveTo(0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0, 0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0);
+ @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0, 0);
+ @assert throws TypeError ctx.arcTo();
+ @assert throws TypeError ctx.arcTo(0);
+ @assert throws TypeError ctx.arcTo(0, 0);
+ @assert throws TypeError ctx.arcTo(0, 0, 0);
+ @assert throws TypeError ctx.arcTo(0, 0, 0, 0);
+ @assert throws TypeError ctx.rect();
+ @assert throws TypeError ctx.rect(0);
+ @assert throws TypeError ctx.rect(0, 0);
+ @assert throws TypeError ctx.rect(0, 0, 0);
+ @assert throws TypeError ctx.arc();
+ @assert throws TypeError ctx.arc(0);
+ @assert throws TypeError ctx.arc(0, 0);
+ @assert throws TypeError ctx.arc(0, 0, 1);
+ @assert throws TypeError ctx.arc(0, 0, 1, 0);
+ // (6th argument to arc is optional)
+ if (ctx.isPointInPath) {
+ @assert throws TypeError ctx.isPointInPath();
+ @assert throws TypeError ctx.isPointInPath(0);
+ }
+ if (ctx.drawFocusRing) {
+ @assert throws TypeError ctx.drawFocusRing();
+ @assert throws TypeError ctx.drawFocusRing(canvas);
+ @assert throws TypeError ctx.drawFocusRing(canvas, 0);
+ }
+ if (ctx.fillText) {
+ @assert throws TypeError ctx.fillText();
+ @assert throws TypeError ctx.fillText('test');
+ @assert throws TypeError ctx.fillText('test', 0);
+ @assert throws TypeError ctx.strokeText();
+ @assert throws TypeError ctx.strokeText('test');
+ @assert throws TypeError ctx.strokeText('test', 0);
+ @assert throws TypeError ctx.measureText();
+ }
+ @assert throws TypeError ctx.drawImage();
+ @assert throws TypeError ctx.drawImage(canvas);
+ @assert throws TypeError ctx.drawImage(canvas, 0);
+ // TODO: n >= 3 args on drawImage could be either a valid overload,
+ // or too few for another overload, or too many for another
+ // overload - what should happen?
+ if (ctx.createImageData) {
+ @assert throws TypeError ctx.createImageData();
+ @assert throws TypeError ctx.createImageData(1);
+ }
+ if (ctx.getImageData) {
+ @assert throws TypeError ctx.getImageData();
+ @assert throws TypeError ctx.getImageData(0);
+ @assert throws TypeError ctx.getImageData(0, 0);
+ @assert throws TypeError ctx.getImageData(0, 0, 1);
+ }
+ if (ctx.putImageData) {
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ @assert throws TypeError ctx.putImageData();
+ @assert throws TypeError ctx.putImageData(imgdata);
+ @assert throws TypeError ctx.putImageData(imgdata, 0);
+ }
+ var g = ctx.createLinearGradient(0, 0, 0, 0);
+ @assert throws TypeError g.addColorStop(); @moz-todo
+ @assert throws TypeError g.addColorStop(0); @moz-todo
+
+
+- name: 2d.conformance.requirements.drawings
+ desc: void methods return undefined
+ images:
+ - yellow.png
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 1, 1, 0, 0, 0, 0) === undefined;
+
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
new file mode 100644
index 0000000000..93c556288d
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml
@@ -0,0 +1,640 @@
+- name: 2d.drawImage.canvas
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(canvas2, 0, 0);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+ ctx.drawImage(document.createElement('canvas'), 0, 0);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.self.1
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.drawImage(canvas, 50, 0);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.self.2
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 1, 100, 49);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 1);
+ ctx.drawImage(canvas, 0, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 2);
+
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.null
+ code: |
+ @assert throws TypeError ctx.drawImage(null, 0, 0);
+
+- name: 2d.drawImage.wrongtype
+ desc: Incorrect image types in drawImage do not match any defined overloads, so
+ WebIDL throws a TypeError
+ code: |
+ @assert throws TypeError ctx.drawImage(undefined, 0, 0);
+ @assert throws TypeError ctx.drawImage(0, 0, 0);
+ @assert throws TypeError ctx.drawImage("", 0, 0);
+
+- name: 2d.drawImage.wrongtype.paragraph
+ desc: Incorrect image types in drawImage do not match any defined overloads, so
+ WebIDL throws a TypeError
+ notes: &bindings Defined in "Web IDL" (draft)
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert throws TypeError ctx.drawImage(document.createElement('p'), 0, 0);
+
+- name: 2d.drawImage.incomplete.nosrc
+ canvasType: ['HTMLCanvas']
+ mozilla: {throws: !!null ''}
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = new Image();
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.incomplete.immediate
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = new Image();
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.drawImage.incomplete.reload
+ canvasType: ['HTMLCanvas']
+ images:
+ - yellow.png
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('yellow.png');
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm,
+ // and resets the image to the "unavailable" state.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.drawImage.incomplete.emptysrc
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ mozilla: {throws: !!null ''}
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('red.png');
+ img.src = "";
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.incomplete.removedsrc
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ mozilla: {throws: !!null ''}
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = document.getElementById('red.png');
+ img.removeAttribute('src');
+ ctx.drawImage(img, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.nonexistent
+ canvasType: ['HTMLCanvas']
+ images:
+ - not-found-at-all.png
+ code: |
+ var img = document.getElementById('not-found-at-all.png');
+ @assert throws INVALID_STATE_ERR ctx.drawImage(img, 0, 0);
+
+- name: 2d.drawImage.zerocanvas
+ desc: drawImage with zero-sized canvas as the source shoud throw exception
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 0;
+ canvas2.height = 50;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+ canvas2.width = 50;
+ canvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+ canvas2.width = 0;
+ canvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0);
+
+- name: 2d.drawImage.animated.gif
+ desc: drawImage() of an animated GIF draws the first frame
+ canvasType: ['HTMLCanvas']
+ images:
+ - anim-gr.gif
+ code: |
+ deferTest();
+ step_timeout(t.step_func_done(function () {
+ ctx.drawImage(document.getElementById('anim-gr.gif'), 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ }), 500);
+ expected: green
+
+# TODO: drawImage shadows
+
+- name: 2d.drawImage.3arg
+ test_type: promise
+ code: |
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0);
+ ctx.drawImage(bitmap_red, -100, 0);
+ ctx.drawImage(bitmap_red, 100, 0);
+ ctx.drawImage(bitmap_red, 0, -50);
+ ctx.drawImage(bitmap_red, 0, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+- name: 2d.drawImage.5arg
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+- name: 2d.drawImage.9arg.basic
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0, 100, 50, 0, 0, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.sourcepos
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 140, 20, 100, 50, 0, 0, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.sourcesize
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/rgrg-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 0, 256, 256, 0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 51, 26);
+ ctx.fillRect(49, 24, 51, 26);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+ @assert pixel 20,20 ==~ 0,255,0,255;
+ @assert pixel 80,20 ==~ 0,255,0,255;
+ @assert pixel 20,30 ==~ 0,255,0,255;
+ @assert pixel 80,30 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.9arg.destpos
+ test_type: promise
+ code: |
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 0, 0, 100, 50, -100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -50, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 50);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+- name: 2d.drawImage.9arg.destsize
+ test_type: promise
+ code: |
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 1, 1, 1, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, -50, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 100, 0, 50, 50);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, -25, 100, 25);
+ ctx.drawImage(bitmap_red, 0, 0, 100, 50, 0, 50, 100, 25);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+- name: 2d.drawImage.canvas
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 0,0 ==~ 0,255,0,255;
+ @assert pixel 99,0 ==~ 0,255,0,255;
+ @assert pixel 0,49 ==~ 0,255,0,255;
+ @assert pixel 99,49 ==~ 0,255,0,255;
+
+- name: 2d.drawImage.zerocanvas
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(0, 10);
+ @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
+
+ offscreenCanvas2.width = 10;
+ offscreenCanvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
+
+ offscreenCanvas2.width = 0;
+ offscreenCanvas2.height = 0;
+ @assert throws INVALID_STATE_ERR ctx.drawImage(offscreenCanvas2, 0, 0);
+
+- name: 2d.drawImage.floatsource
+ test_type: promise
+ code: |
+ const response = await fetch('/images/green.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ Expected: green
+
+- name: 2d.drawImage.zerosource
+ desc: drawImage with zero-sized source rectangle draws nothing without exception
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 10, 10, 0, 1, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 1, 0, 0, 0, 100, 50);
+ ctx.drawImage(bitmap, 10, 10, 0, 0, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.zerosource.image
+ desc: drawImage with zero-sized source rectangle from image draws nothing without exception
+ test_type: promise
+ canvasType: ['HTMLCanvas', 'OffscreenCanvas']
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ function loadImage(src) {
+ return new Promise((resolve, reject) => {
+ const img = new Image();
+ img.onload = () => resolve(img);
+ img.onerror = (err) => reject(err);
+ img.src = src;
+ });
+ }
+ const img1 = await loadImage('/images/red-zerowidth.svg');
+ const img2 = await loadImage('/images/red-zeroheight.svg');
+ const img3 = await loadImage('/images/red-zerosize.svg');
+
+ ctx.drawImage(img1, 0, 0, 100, 50);
+ ctx.drawImage(img2, 0, 0, 100, 50);
+ ctx.drawImage(img3, 0, 0, 100, 50);
+ _assertPixel(canvas, 50, 25, 0, 255, 0, 255);
+ expected: green
+
+
+- name: 2d.drawImage.negativesource
+ desc: Negative source width/height represents the correct rectangle
+ mozilla: {throws: !!null ''}
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, -100, 50, 0, 0, 50, 50);
+ ctx.drawImage(bitmap, 100, 128, -100, -50, 50, 0, 50, 50);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.negativedest
+ desc: Negative destination width/height represents the correct rectangle
+ mozilla: {throws: !!null ''}
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 100, 78, 50, 50, 0, 50, 50, -50);
+ ctx.drawImage(bitmap, 100, 128, 50, -50, 100, 50, -50, -50);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.negativedir
+ desc: Negative dimensions do not affect the direction of the image
+ mozilla: {throws: !!null ''}
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/ggrr-256x256.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+ ctx.drawImage(bitmap, 0, 178, 50, -100, 0, 0, 50, 100);
+ ctx.drawImage(bitmap, 0, 78, 50, 100, 50, 100, 50, -100);
+ @assert pixel 1,1 ==~ 0,255,0,255;
+ @assert pixel 1,48 ==~ 0,255,0,255;
+ @assert pixel 98,1 ==~ 0,255,0,255;
+ @assert pixel 98,48 ==~ 0,255,0,255;
+ @assert pixel 48,1 ==~ 0,255,0,255;
+ @assert pixel 48,48 ==~ 0,255,0,255;
+ @assert pixel 51,1 ==~ 0,255,0,255;
+ @assert pixel 51,48 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.outsidesource
+ DISABLED: fix this to match the current spec (transparent black outside source)
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ const response_red = await fetch('/images/red.png');
+ const blob_red = await response_red.blob();
+ const bitmap_red = await createImageBitmap(blob_red);
+
+ const response_green = await fetch('/images/green.png');
+ const blob_green = await response_green.blob();
+ const bitmap_green = await createImageBitmap(blob_green);
+ ctx.drawImage(bitmap_green, 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
+ ctx.drawImage(bitmap_green, 100, 50, -5, -5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, -0.001, 0, 100, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, -0.001, 100, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, 100.001, 50, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, 100, 50.001, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, -5, 5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 0, 0, 5, -5, 0, 0, 100, 50);
+ @assert throws INDEX_SIZE_ERR ctx.drawImage(bitmap1, 110, 60, -20, -20, 0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.drawImage.broken
+ test_type: promise
+ code: |
+ const response = await fetch('/images/broken.png');
+ const blob = await response.blob();
+
+ await promise_rejects_dom(t, 'InvalidStateError', createImageBitmap(blob), 'The source image could not be decoded.');
+ expected: green
+
+- name: 2d.drawImage.svg
+ desc: drawImage() of an SVG image
+ test_type: promise
+ canvasType: ['HTMLCanvas', 'OffscreenCanvas']
+ code: |
+ const img = new Image();
+ const imageLoadPromise = new Promise((resolve, reject) => {
+ img.onload = () => resolve();
+ img.onerror = (err) => reject(err);
+ });
+ img.src = '/images/green.svg';
+ await imageLoadPromise;
+
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50, 25, 0, 255, 0, 255, 2);
+ expected: green
+
+- name: 2d.drawImage.path
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ ctx.fill();
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.transform
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(100, 0);
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.alpha
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0;
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.clip
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.composite
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ const response = await fetch('/images/red.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.nowrap
+ desc: Stretched images do not get pixels wrapping around the edges
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ ctx.drawImage(bitmap, -1950, 0, 2000, 50);
+ @assert pixel 45,25 ==~ 0,255,0,255;
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 55,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.drawImage.nonfinite
+ desc: drawImage() with Infinity/NaN is ignored
+ test_type: promise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ const response = await fetch('/images/redtransparent.png');
+ const blob = await response.blob();
+ const bitmap = await createImageBitmap(blob);
+
+ @nonfinite ctx.drawImage(<bitmap>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+ @nonfinite ctx.drawImage(<bitmap>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @nonfinite ctx.drawImage(<bitmap>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml
new file mode 100644
index 0000000000..408e932abe
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-rectangles-to-the-canvas.yaml
@@ -0,0 +1,469 @@
+- name: 2d.clearRect.basic
+ desc: clearRect clears to transparent black
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.path
+ desc: clearRect does not affect the current path
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 16, 16);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.zero
+ desc: clearRect of zero pixels has no effect
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 100, 0);
+ ctx.clearRect(0, 0, 0, 50);
+ ctx.clearRect(0, 0, 0, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.negative
+ desc: clearRect of negative sizes works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 50, 25);
+ ctx.clearRect(100, 0, -50, 25);
+ ctx.clearRect(0, 50, 50, -25);
+ ctx.clearRect(100, 50, -50, -25);
+ @assert pixel 25,12 == 0,0,0,0;
+ @assert pixel 75,12 == 0,0,0,0;
+ @assert pixel 25,37 == 0,0,0,0;
+ @assert pixel 75,37 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.transform
+ desc: clearRect is affected by transforms
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.clearRect(0, -5, 10, 5);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.globalalpha
+ desc: clearRect is not affected by globalAlpha
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.1;
+ ctx.clearRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.globalcomposite
+ desc: clearRect is not affected by globalCompositeOperation
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.clearRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.clearRect.clip
+ desc: clearRect is affected by clipping regions
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.shadow
+ desc: clearRect does not draw shadows
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.clearRect(0, -50, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.clearRect.nonfinite
+ desc: clearRect() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @nonfinite ctx.clearRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.fillRect.basic
+ desc: fillRect works
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.path
+ desc: fillRect does not affect the current path
+ code: |
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.zero
+ desc: fillRect of zero pixels has no effect
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 0);
+ ctx.fillRect(0, 0, 0, 50);
+ ctx.fillRect(0, 0, 0, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.negative
+ desc: fillRect of negative sizes works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillRect(100, 0, -50, 25);
+ ctx.fillRect(0, 50, 50, -25);
+ ctx.fillRect(100, 50, -50, -25);
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.transform
+ desc: fillRect is affected by transforms
+ code: |
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -5, 10, 5);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+# don't bother testing globalalpha, globalcomposite because they're already heavily used by other test cases
+
+- name: 2d.fillRect.clip
+ desc: fillRect is affected by clipping regions
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.shadow
+ desc: fillRect draws shadows
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillRect.nonfinite
+ desc: fillRect() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ @nonfinite ctx.fillRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.strokeRect.basic
+ desc: strokeRect works
+ code: |
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.path
+ desc: strokeRect does not affect the current path
+ code: |
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.zero.1
+ desc: strokeRect of 0x0 pixels draws nothing
+ code: |
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.strokeRect(50, 25, 0, 0);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.zero.2
+ desc: strokeRect of 0x0 pixels draws nothing, including caps and joins
+ code: |
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(50, 25, 0, 0);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.zero.3
+ desc: strokeRect of Nx0 pixels draws a straight line
+ code: |
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 25, 100, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.zero.4
+ desc: strokeRect of Nx0 pixels draws a closed line with no caps
+ code: |
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 250;
+ ctx.lineCap = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.zero.5
+ desc: strokeRect of Nx0 pixels draws a closed line with joins
+ code: |
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 250;
+ ctx.lineJoin = 'round';
+ ctx.strokeRect(100, 25, 100, 0);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.negative
+ desc: strokeRect of negative sizes works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 25;
+ ctx.strokeRect(12, 12, 26, 1);
+ ctx.strokeRect(88, 12, -26, 1);
+ ctx.strokeRect(12, 38, 26, -1);
+ ctx.strokeRect(88, 38, -26, -1);
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.transform
+ desc: fillRect is affected by transforms
+ code: |
+ ctx.scale(10, 10);
+ ctx.translate(0, 5);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(2.5, -2.6, 5, 0.2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.globalalpha
+ desc: strokeRect is affected by globalAlpha
+ code: |
+ ctx.globalAlpha = 0;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.globalcomposite
+ desc: strokeRect is not affected by globalCompositeOperation
+ code: |
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ expected: clear
+
+- name: 2d.strokeRect.clip
+ desc: strokeRect is affected by clipping regions
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.rect(0, 0, 16, 16);
+ ctx.clip();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 16);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.shadow
+ desc: strokeRect draws shadows
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0;
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.strokeRect(0, -75, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeRect.nonfinite
+ desc: strokeRect() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 150;
+ @nonfinite ctx.strokeRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.colorObject
+ desc: ctx.fillStyle works with color objects
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = {r: 1, g: 0, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 255,0,0,255;
+ ctx.fillStyle = {r: 0, g: 0, b: 1};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,255,255;
+ ctx.fillStyle = {r: 0.2, g: 0.4, b: 0.6};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 51,102,153,255;
+ ctx.fillStyle = {r: 0, g: 1, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ ctx.fillStyle = {r: -1, g: 0, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,255;
+ ctx.fillStyle = {r: 0, g: 2, b: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.colorObject.transparency
+ desc: ctx.fillStyle with color objects has transparency
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 0};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: -1};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 0.5};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,128;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.fillStyle = {r: 0, g: 1, b: 0, a: 1};
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeStyle.colorObject
+ desc: ctx.strokeStyle works with color objects
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = {r: 1, g: 0, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 255,0,0,255;
+ ctx.strokeStyle = {r: 0, g: 0, b: 1};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,255,255;
+ ctx.strokeStyle = {r: 0.2, g: 0.4, b: 0.6};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 51,102,153,255;
+ ctx.strokeStyle = {r: 0, g: 1, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ ctx.strokeStyle = {r: -1, g: 0, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,255;
+ ctx.strokeStyle = {r: 0, g: 2, b: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.strokeStyle.colorObject.transparency
+ desc: ctx.strokeStyle with color objects has transparency
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 0};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: -1};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,0,0,0;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 0.5};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,128;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.strokeStyle = {r: 0, g: 1, b: 0, a: 1};
+ ctx.strokeRect(25, 24, 50, 2);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/fill-and-stroke-styles.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/fill-and-stroke-styles.yaml
new file mode 100644
index 0000000000..c992af6e7c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/fill-and-stroke-styles.yaml
@@ -0,0 +1,2104 @@
+- name: 2d.fillStyle.parse.current.basic
+ desc: currentColor is computed from the canvas element
+ canvasType: ['HtmlCanvas']
+ code: |
+ canvas.setAttribute('style', 'color: #0f0');
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'currentColor';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.parse.current.changed
+ desc: currentColor is computed when the attribute is set, not when it is painted
+ canvasType: ['HtmlCanvas']
+ code: |
+ canvas.setAttribute('style', 'color: #0f0');
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = 'currentColor';
+ canvas.setAttribute('style', 'color: #f00');
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.parse.current.removed
+ desc: currentColor is solid black when the canvas element is not in a document
+ canvasType: ['HtmlCanvas']
+ code: |
+ // Try not to let it undetectably incorrectly pick up opaque-black
+ // from other parts of the document:
+ document.body.parentNode.setAttribute('style', 'color: #f00');
+ document.body.setAttribute('style', 'color: #f00');
+ canvas.setAttribute('style', 'color: #f00');
+
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillStyle = 'currentColor';
+ ctx2.fillRect(0, 0, 100, 50);
+ ctx.drawImage(canvas2, 0, 0);
+
+ document.body.parentNode.removeAttribute('style');
+ document.body.removeAttribute('style');
+
+ @assert pixel 50,25 == 0,0,0,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0, 0, 0)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.fillStyle.invalidstring
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = 'invalid';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.invalidtype
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillStyle = null;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.fillStyle.get.solid
+ code: |
+ ctx.fillStyle = '#fa0';
+ @assert ctx.fillStyle === '#ffaa00';
+
+- name: 2d.fillStyle.get.semitransparent
+ code: |
+ ctx.fillStyle = 'rgba(255,255,255,0.45)';
+ @assert ctx.fillStyle =~ /^rgba\(255, 255, 255, 0\.4\d+\)$/;
+
+- name: 2d.fillStyle.get.halftransparent
+ code: |
+ ctx.fillStyle = 'rgba(255,255,255,0.5)';
+ @assert ctx.fillStyle === 'rgba(255, 255, 255, 0.5)';
+
+- name: 2d.fillStyle.get.transparent
+ code: |
+ ctx.fillStyle = 'rgba(0,0,0,0)';
+ @assert ctx.fillStyle === 'rgba(0, 0, 0, 0)';
+
+- name: 2d.fillStyle.default
+ code: |
+ @assert ctx.fillStyle === '#000000';
+
+- name: 2d.fillStyle.toStringFunctionCallback
+ desc: Passing a function in to ctx.fillStyle or ctx.strokeStyle with a toString callback works as specified
+ code: |
+ ctx.fillStyle = { toString: function() { return "#008000"; } };
+ @assert ctx.fillStyle === "#008000";
+ ctx.fillStyle = {};
+ @assert ctx.fillStyle === "#008000";
+ ctx.fillStyle = 800000;
+ @assert ctx.fillStyle === "#008000";
+ @assert throws TypeError ctx.fillStyle = { toString: function() { throw new TypeError; } };
+ ctx.strokeStyle = { toString: function() { return "#008000"; } };
+ @assert ctx.strokeStyle === "#008000";
+ ctx.strokeStyle = {};
+ @assert ctx.strokeStyle === "#008000";
+ ctx.strokeStyle = 800000;
+ @assert ctx.strokeStyle === "#008000";
+ @assert throws TypeError ctx.strokeStyle = { toString: function() { throw new TypeError; } };
+
+- name: 2d.strokeStyle.default
+ code: |
+ @assert ctx.strokeStyle === '#000000';
+
+
+- name: 2d.gradient.object.type
+ desc: window.CanvasGradient exists and has the right properties
+ notes: &bindings Defined in "Web IDL" (draft)
+ code: |
+ {% set root = 'self' if canvas_type == 'worker' else 'window' %}
+ @assert {{ root }}.CanvasGradient !== undefined;
+ @assert {{ root }}.CanvasGradient.prototype.addColorStop !== undefined;
+
+- name: 2d.gradient.object.return
+ desc: createLinearGradient() and createRadialGradient() returns objects implementing
+ CanvasGradient
+ code: |
+ {% set root = 'self' if canvas_type == 'worker' else 'window' %}
+ {{ root }}.CanvasGradient.prototype.thisImplementsCanvasGradient = true;
+
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ @assert g1.addColorStop !== undefined;
+ @assert g1.thisImplementsCanvasGradient === true;
+
+ var g2 = ctx.createRadialGradient(0, 0, 10, 0, 0, 20);
+ @assert g2.addColorStop !== undefined;
+ @assert g2.thisImplementsCanvasGradient === true;
+
+- name: 2d.gradient.interpolate.solid
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.interpolate.color
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 25,25 ==~ 191,191,63,255 +/- 3;
+ @assert pixel 50,25 ==~ 127,127,127,255 +/- 3;
+ @assert pixel 75,25 ==~ 63,63,191,255 +/- 3;
+ expected: |
+ size 100 50
+ g = cairo.LinearGradient(0, 0, 100, 0)
+ g.add_color_stop_rgb(0, 1,1,0)
+ g.add_color_stop_rgb(1, 0,0,1)
+ cr.set_source(g)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.gradient.interpolate.alpha
+ code: |
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(0,0,255, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 25,25 ==~ 191,191,63,255 +/- 3;
+ @assert pixel 50,25 ==~ 127,127,127,255 +/- 3;
+ @assert pixel 75,25 ==~ 63,63,191,255 +/- 3;
+ expected: |
+ size 100 50
+ g = cairo.LinearGradient(0, 0, 100, 0)
+ g.add_color_stop_rgb(0, 1,1,0)
+ g.add_color_stop_rgb(1, 0,0,1)
+ cr.set_source(g)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.gradient.interpolate.coloralpha
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(255,255,0, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 25,25 ==~ 190,190,65,65 +/- 3;
+ @assert pixel 50,25 ==~ 126,126,128,128 +/- 3;
+ @assert pixel 75,25 ==~ 62,62,192,192 +/- 3;
+ expected: |
+ size 100 50
+ g = cairo.LinearGradient(0, 0, 100, 0)
+ g.add_color_stop_rgba(0, 1,1,0, 0)
+ g.add_color_stop_rgba(1, 0,0,1, 1)
+ cr.set_source(g)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.gradient.interpolate.outside
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(25, 0, 75, 0);
+ g.addColorStop(0.4, '#0f0');
+ g.addColorStop(0.6, '#0f0');
+
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 20,25 ==~ 0,255,0,255;
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 80,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.interpolate.zerosize.fill
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ @assert pixel 40,20 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.interpolate.zerosize.stroke
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.rect(20, 20, 60, 10);
+ ctx.stroke();
+ @assert pixel 19,19 == 0,255,0,255;
+ @assert pixel 20,19 == 0,255,0,255;
+ @assert pixel 21,19 == 0,255,0,255;
+ @assert pixel 19,20 == 0,255,0,255;
+ @assert pixel 20,20 == 0,255,0,255;
+ @assert pixel 21,20 == 0,255,0,255;
+ @assert pixel 19,21 == 0,255,0,255;
+ @assert pixel 20,21 == 0,255,0,255;
+ @assert pixel 21,21 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.interpolate.zerosize.fillRect
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 40,20 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.gradient.interpolate.zerosize.strokeRect
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.strokeRect(20, 20, 60, 10);
+ @assert pixel 19,19 == 0,255,0,255;
+ @assert pixel 20,19 == 0,255,0,255;
+ @assert pixel 21,19 == 0,255,0,255;
+ @assert pixel 19,20 == 0,255,0,255;
+ @assert pixel 20,20 == 0,255,0,255;
+ @assert pixel 21,20 == 0,255,0,255;
+ @assert pixel 19,21 == 0,255,0,255;
+ @assert pixel 20,21 == 0,255,0,255;
+ @assert pixel 21,21 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.interpolate.zerosize.fillText
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.fillText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+ expected: green
+
+- name: 2d.gradient.interpolate.zerosize.strokeText
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.strokeStyle = g;
+ ctx.font = '100px sans-serif';
+ ctx.strokeText("AA", 0, 50);
+ _assertGreen(ctx, 100, 50);
+ expected: green
+
+
+- name: 2d.gradient.interpolate.vertical
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,12 ==~ 191,191,63,255 +/- 10;
+ @assert pixel 50,25 ==~ 127,127,127,255 +/- 5;
+ @assert pixel 50,37 ==~ 63,63,191,255 +/- 10;
+ expected: |
+ size 100 50
+ g = cairo.LinearGradient(0, 0, 0, 50)
+ g.add_color_stop_rgb(0, 1,1,0)
+ g.add_color_stop_rgb(1, 0,0,1)
+ cr.set_source(g)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.gradient.interpolate.multiple
+ code: |
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.5, '#0ff');
+ g.addColorStop(1, '#f0f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ @assert pixel 50,25 ==~ 127,255,127,255 +/- 3;
+ @assert pixel 100,25 ==~ 0,255,255,255 +/- 3;
+ @assert pixel 150,25 ==~ 127,127,255,255 +/- 3;
+ expected: |
+ size 200 50
+ g = cairo.LinearGradient(0, 0, 200, 0)
+ g.add_color_stop_rgb(0.0, 1,1,0)
+ g.add_color_stop_rgb(0.5, 0,1,1)
+ g.add_color_stop_rgb(1.0, 1,0,1)
+ cr.set_source(g)
+ cr.rectangle(0, 0, 200, 50)
+ cr.fill()
+
+- name: 2d.gradient.interpolate.overlap
+ code: |
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.25, '#00f');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#ff0');
+ g.addColorStop(0.5, '#00f');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.75, '#00f');
+ g.addColorStop(0.75, '#f00');
+ g.addColorStop(0.75, '#ff0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ @assert pixel 49,25 ==~ 0,0,255,255 +/- 16;
+ @assert pixel 51,25 ==~ 255,255,0,255 +/- 16;
+ @assert pixel 99,25 ==~ 0,0,255,255 +/- 16;
+ @assert pixel 101,25 ==~ 255,255,0,255 +/- 16;
+ @assert pixel 149,25 ==~ 0,0,255,255 +/- 16;
+ @assert pixel 151,25 ==~ 255,255,0,255 +/- 16;
+ expected: |
+ size 200 50
+ g = cairo.LinearGradient(0, 0, 50, 0)
+ g.add_color_stop_rgb(0, 1,1,0)
+ g.add_color_stop_rgb(1, 0,0,1)
+ cr.set_source(g)
+ cr.rectangle(0, 0, 50, 50)
+ cr.fill()
+
+ g = cairo.LinearGradient(50, 0, 100, 0)
+ g.add_color_stop_rgb(0, 1,1,0)
+ g.add_color_stop_rgb(1, 0,0,1)
+ cr.set_source(g)
+ cr.rectangle(50, 0, 50, 50)
+ cr.fill()
+
+ g = cairo.LinearGradient(100, 0, 150, 0)
+ g.add_color_stop_rgb(0, 1,1,0)
+ g.add_color_stop_rgb(1, 0,0,1)
+ cr.set_source(g)
+ cr.rectangle(100, 0, 50, 50)
+ cr.fill()
+
+ g = cairo.LinearGradient(150, 0, 200, 0)
+ g.add_color_stop_rgb(0, 1,1,0)
+ g.add_color_stop_rgb(1, 0,0,1)
+ cr.set_source(g)
+ cr.rectangle(150, 0, 50, 50)
+ cr.fill()
+
+- name: 2d.gradient.interpolate.overlap2
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
+ for (var p = 0; p < ps.length; ++p)
+ {
+ g.addColorStop(ps[p], '#0f0');
+ for (var i = 0; i < 15; ++i)
+ g.addColorStop(ps[p], '#f00');
+ g.addColorStop(ps[p], '#0f0');
+ }
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 30,25 == 0,255,0,255;
+ @assert pixel 40,25 == 0,255,0,255;
+ @assert pixel 60,25 == 0,255,0,255;
+ @assert pixel 80,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.empty
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.object.update
+ code: |
+ var g = ctx.createLinearGradient(-100, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ g.addColorStop(0.1, '#0f0');
+ g.addColorStop(0.9, '#0f0');
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.object.compare
+ code: |
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ var g2 = ctx.createLinearGradient(0, 0, 100, 0);
+ @assert g1 !== g2;
+ ctx.fillStyle = g1;
+ @assert ctx.fillStyle === g1;
+
+- name: 2d.gradient.object.crosscanvas
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = {{ create_canvas }}.getContext('2d').createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+ variants:
+ _HtmlCanvas:
+ canvasType: ['HtmlCanvas']
+ create_canvas: document.createElement('canvas')
+ _OffscreenCanvas:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ create_canvas: new OffscreenCanvas(100, 50)
+
+- name: 2d.gradient.object.current
+ canvasType: ['HtmlCanvas']
+ code: |
+ canvas.setAttribute('style', 'color: #f00');
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'currentColor');
+ g.addColorStop(1, 'currentColor');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 0,0,0,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0, 0, 0)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.gradient.object.invalidoffset
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ @assert throws INDEX_SIZE_ERR g.addColorStop(-1, '#000');
+ @assert throws INDEX_SIZE_ERR g.addColorStop(2, '#000');
+ @assert throws TypeError g.addColorStop(Infinity, '#000');
+ @assert throws TypeError g.addColorStop(-Infinity, '#000');
+ @assert throws TypeError g.addColorStop(NaN, '#000');
+
+- name: 2d.gradient.object.invalidcolor
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ @assert throws SYNTAX_ERR g.addColorStop(0, "");
+ @assert throws SYNTAX_ERR g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)');
+ @assert throws SYNTAX_ERR g.addColorStop(0, 'null');
+ @assert throws SYNTAX_ERR g.addColorStop(0, 'undefined');
+ @assert throws SYNTAX_ERR g.addColorStop(0, null);
+ @assert throws SYNTAX_ERR g.addColorStop(0, undefined);
+
+ var g = ctx.createRadialGradient(0, 0, 0, 100, 0, 0);
+ @assert throws SYNTAX_ERR g.addColorStop(0, "");
+ @assert throws SYNTAX_ERR g.addColorStop(0, 'rgb(NaN%, NaN%, NaN%)');
+ @assert throws SYNTAX_ERR g.addColorStop(0, 'null');
+ @assert throws SYNTAX_ERR g.addColorStop(0, 'undefined');
+ @assert throws SYNTAX_ERR g.addColorStop(0, null);
+ @assert throws SYNTAX_ERR g.addColorStop(0, undefined);
+
+
+- name: 2d.gradient.linear.nonfinite
+ desc: createLinearGradient() throws TypeError if arguments are not finite
+ notes: *bindings
+ code: |
+ @nonfinite @assert throws TypeError ctx.createLinearGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+
+- name: 2d.gradient.linear.transform.1
+ desc: Linear gradient coordinates are relative to the coordinate space at the time
+ of filling
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.linear.transform.2
+ desc: Linear gradient coordinates are relative to the coordinate space at the time
+ of filling
+ code: |
+ ctx.translate(100, 0);
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-150, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.linear.transform.3
+ desc: Linear gradient transforms do not experience broken caching effects
+ code: |
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.negative
+ desc: createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative
+ code: |
+ @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1);
+ @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1);
+ @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1);
+
+- name: 2d.gradient.radial.nonfinite
+ desc: createRadialGradient() throws TypeError if arguments are not finite
+ notes: *bindings
+ code: |
+ @nonfinite @assert throws TypeError ctx.createRadialGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>);
+
+- name: 2d.gradient.radial.inside1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.inside2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.inside3
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.993, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.outside1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.outside2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.outside3
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.001, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.touch1
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255; @moz-todo
+ @assert pixel 50,1 == 0,255,0,255; @moz-todo
+ @assert pixel 98,1 == 0,255,0,255; @moz-todo
+ @assert pixel 1,25 == 0,255,0,255; @moz-todo
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 1,48 == 0,255,0,255; @moz-todo
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 98,48 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.gradient.radial.touch2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.01, '#0f0');
+ g.addColorStop(0.99, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.touch3
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255; @moz-todo
+ @assert pixel 50,1 == 0,255,0,255; @moz-todo
+ @assert pixel 98,1 == 0,255,0,255; @moz-todo
+ @assert pixel 1,25 == 0,255,0,255; @moz-todo
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 1,48 == 0,255,0,255; @moz-todo
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 98,48 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.gradient.radial.equal
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255; @moz-todo
+ @assert pixel 50,1 == 0,255,0,255; @moz-todo
+ @assert pixel 98,1 == 0,255,0,255; @moz-todo
+ @assert pixel 1,25 == 0,255,0,255; @moz-todo
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 1,48 == 0,255,0,255; @moz-todo
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 98,48 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.gradient.radial.cone.behind
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255; @moz-todo
+ @assert pixel 50,1 == 0,255,0,255; @moz-todo
+ @assert pixel 98,1 == 0,255,0,255; @moz-todo
+ @assert pixel 1,25 == 0,255,0,255; @moz-todo
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 1,48 == 0,255,0,255; @moz-todo
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 98,48 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.gradient.radial.cone.front
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.cone.bottom
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.cone.top
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.cone.beside
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255; @moz-todo
+ @assert pixel 50,1 == 0,255,0,255; @moz-todo
+ @assert pixel 98,1 == 0,255,0,255; @moz-todo
+ @assert pixel 1,25 == 0,255,0,255; @moz-todo
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 1,48 == 0,255,0,255; @moz-todo
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1; @moz-todo
+ @assert pixel 98,48 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.gradient.radial.cone.cylinder
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.cone.shape1
+ code: |
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(30+tol, 40);
+ ctx.lineTo(110, -20+tol);
+ ctx.lineTo(110, 100-tol);
+ ctx.fill();
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.cone.shape2
+ code: |
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(30-tol, 40);
+ ctx.lineTo(110, -20-tol);
+ ctx.lineTo(110, 100+tol);
+ ctx.fill();
+
+ @assert pixel 1,1 == 0,255,0,255; @moz-todo
+ @assert pixel 50,1 == 0,255,0,255; @moz-todo
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255; @moz-todo
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 1,48 == 0,255,0,255; @moz-todo
+ @assert pixel 50,48 ==~ 0,255,0,255 +/- 1;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.transform.1
+ desc: Radial gradient coordinates are relative to the coordinate space at the time
+ of filling
+ code: |
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.transform.2
+ desc: Radial gradient coordinates are relative to the coordinate space at the time
+ of filling
+ code: |
+ ctx.translate(100, 0);
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.radial.transform.3
+ desc: Radial gradient transforms do not experience broken caching effects
+ code: |
+ var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.gradient.conic.positive.rotation
+ desc: Conic gradient with positive rotation
+ code: |
+ const g = ctx.createConicGradient(3*Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 25,15 ==~ 255,0,0,255 +/- 3;
+ @assert pixel 75,40 ==~ 0,255,0,255 +/- 3;
+ expected: green
+
+- name: 2d.gradient.conic.negative.rotation
+ desc: Conic gradient with negative rotation
+ code: |
+ const g = ctx.createConicGradient(-Math.PI/2, 50, 25);
+ // It's red in the upper right region and green on the lower left region
+ g.addColorStop(0, "#f00");
+ g.addColorStop(0.25, "#0f0");
+ g.addColorStop(0.50, "#0f0");
+ g.addColorStop(0.75, "#f00");
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 25,15 ==~ 255,0,0,255 +/- 3;
+ @assert pixel 75,40 ==~ 0,255,0,255 +/- 3;
+ expected: green
+
+- name: 2d.gradient.conic.invalid.inputs
+ desc: Conic gradient function with invalid inputs
+ code: |
+ @nonfinite @assert throws TypeError ctx.createConicGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>);
+
+ const g = ctx.createConicGradient(0, 0, 25);
+ @nonfinite @assert throws TypeError g.addColorStop(<Infinity -Infinity NaN>, <'#f00'>);
+ @nonfinite @assert throws SYNTAX_ERR g.addColorStop(<0>, <Infinity -Infinity NaN>);
+
+- name: 2d.pattern.basic.type
+ images:
+ - green.png
+ code: |
+ {% set root = 'self' if canvas_type == 'worker' else 'window' %}
+ @assert {{ root }}.CanvasPattern !== undefined;
+
+ {{ root }}.CanvasPattern.prototype.thisImplementsCanvasPattern = true;
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ @assert pattern.thisImplementsCanvasPattern;
+ variants: &load-image-variant-definition
+ _HtmlCanvas:
+ canvasType: ['HtmlCanvas']
+ load_image: var img = document.getElementById('{{ (images or svgimages)[0] }}');
+ _OffscreenCanvas:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ test_type: promise
+ load_image: |-
+ var response = await fetch('/images/{{ (images or svgimages)[0] }}')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+
+- name: 2d.pattern.basic.image
+ images:
+ - green.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.basic.canvas
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: &create-canvas2-variant-definition
+ _HtmlCanvas:
+ canvasType: ['HtmlCanvas']
+ create_canvas2: |-
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ _OffscreenCanvas:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ create_canvas2: |-
+ var canvas2 = new OffscreenCanvas(100, 50);
+
+- name: 2d.pattern.basic.zerocanvas
+ code: |
+ canvas.width = 0;
+ canvas.height = 10;
+ @assert canvas.width === 0;
+ @assert canvas.height === 10;
+ @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat');
+
+ canvas.width = 10;
+ canvas.height = 0;
+ @assert canvas.width === 10;
+ @assert canvas.height === 0;
+ @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat');
+
+ canvas.width = 0;
+ canvas.height = 0;
+ @assert canvas.width === 0;
+ @assert canvas.height === 0;
+ @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat');
+
+- name: 2d.pattern.basic.nocontext
+ code: |
+ {{ create_canvas2 }}
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.pattern.transform.identity
+ code: |
+ {{ create_canvas2 }}
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform(new DOMMatrix());
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.pattern.transform.infinity
+ code: |
+ {{ create_canvas2 }}
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ pattern.setTransform({a: Infinity});
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.pattern.transform.invalid
+ code: |
+ {{ create_canvas2 }}
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ @assert throws TypeError pattern.setTransform({a: 1, m11: 2});
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.pattern.image.undefined
+ notes: *bindings
+ code: |
+ @assert throws TypeError ctx.createPattern(undefined, 'repeat');
+
+- name: 2d.pattern.image.null
+ notes: *bindings
+ code: |
+ @assert throws TypeError ctx.createPattern(null, 'repeat');
+
+- name: 2d.pattern.image.string
+ notes: *bindings
+ code: |
+ @assert throws TypeError ctx.createPattern('../images/red.png', 'repeat');
+
+- name: 2d.pattern.image.incomplete.nosrc
+ canvasType: ['HtmlCanvas']
+ code: |
+ var img = new Image();
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.image.incomplete.immediate
+ canvasType: ['HtmlCanvas']
+ images:
+ - red.png
+ code: |
+ var img = new Image();
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ @assert ctx.createPattern(img, 'repeat') === null; @moz-todo
+
+- name: 2d.pattern.image.incomplete.reload
+ canvasType: ['HtmlCanvas']
+ images:
+ - yellow.png
+ - red.png
+ code: |
+ var img = document.getElementById('yellow.png');
+ img.src = '../images/red.png';
+ // This triggers the "update the image data" algorithm,
+ // and resets the image to the "unavailable" state.
+ // The image will not go to the "completely available" state
+ // until a fetch task in the networking task source is processed,
+ // so the image must not be fully decodable yet:
+ @assert ctx.createPattern(img, 'repeat') === null; @moz-todo
+
+- name: 2d.pattern.image.incomplete.emptysrc
+ canvasType: ['HtmlCanvas']
+ images:
+ - red.png
+ mozilla: {throws: !!null ''}
+ code: |
+ var img = document.getElementById('red.png');
+ img.src = "";
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.image.incomplete.removedsrc
+ canvasType: ['HtmlCanvas']
+ images:
+ - red.png
+ mozilla: {throws: !!null ''}
+ code: |
+ var img = document.getElementById('red.png');
+ img.removeAttribute('src');
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.image.broken
+ canvasType: ['HtmlCanvas']
+ images:
+ - broken.png
+ code: |
+ var img = document.getElementById('broken.png');
+ @assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
+
+- name: 2d.pattern.image.nonexistent
+ canvasType: ['HtmlCanvas']
+ images:
+ - no-such-image-really.png
+ code: |
+ var img = document.getElementById('no-such-image-really.png');
+ @assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
+
+- name: 2d.pattern.svgimage.nonexistent
+ canvasType: ['HtmlCanvas']
+ svgimages:
+ - no-such-image-really.png
+ code: |
+ var img = document.getElementById('no-such-image-really.png');
+ @assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
+
+- name: 2d.pattern.image.nonexistent-but-loading
+ canvasType: ['HtmlCanvas']
+ code: |
+ var img = document.createElement("img");
+ img.src = "/images/no-such-image-really.png";
+ @assert ctx.createPattern(img, 'repeat') === null;
+ var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ img.src = "/images/no-such-image-really.png";
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.image.nosrc
+ canvasType: ['HtmlCanvas']
+ code: |
+ var img = document.createElement("img");
+ @assert ctx.createPattern(img, 'repeat') === null;
+ var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.image.zerowidth
+ canvasType: ['HtmlCanvas']
+ images:
+ - red-zerowidth.svg
+ code: |
+ var img = document.getElementById('red-zerowidth.svg');
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.image.zeroheight
+ canvasType: ['HtmlCanvas']
+ images:
+ - red-zeroheight.svg
+ code: |
+ var img = document.getElementById('red-zeroheight.svg');
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.svgimage.zerowidth
+ canvasType: ['HtmlCanvas']
+ svgimages:
+ - red-zerowidth.svg
+ code: |
+ var img = document.getElementById('red-zerowidth.svg');
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.svgimage.zeroheight
+ canvasType: ['HtmlCanvas']
+ svgimages:
+ - red-zeroheight.svg
+ code: |
+ var img = document.getElementById('red-zeroheight.svg');
+ @assert ctx.createPattern(img, 'repeat') === null;
+
+- name: 2d.pattern.repeat.empty
+ images:
+ - green-1x1.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, "");
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 200, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.repeat.null
+ code: |
+ @assert ctx.createPattern(canvas, null) != null;
+
+- name: 2d.pattern.repeat.undefined
+ code: |
+ @assert throws SYNTAX_ERR ctx.createPattern(canvas, undefined);
+
+- name: 2d.pattern.repeat.unrecognised
+ code: |
+ @assert throws SYNTAX_ERR ctx.createPattern(canvas, "invalid");
+
+- name: 2d.pattern.repeat.unrecognisednull
+ code: |
+ @assert throws SYNTAX_ERR ctx.createPattern(canvas, "null");
+
+- name: 2d.pattern.repeat.case
+ code: |
+ @assert throws SYNTAX_ERR ctx.createPattern(canvas, "Repeat");
+
+- name: 2d.pattern.repeat.nullsuffix
+ code: |
+ @assert throws SYNTAX_ERR ctx.createPattern(canvas, "repeat\0");
+
+- name: 2d.pattern.modify.image1
+ canvasType: ['HtmlCanvas']
+ images:
+ - green.png
+ code: |
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ deferTest();
+ img.onload = t.step_func_done(function ()
+ {
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ });
+ img.src = '/images/red.png';
+ expected: green
+
+- name: 2d.pattern.modify.image2
+ canvasType: ['HtmlCanvas']
+ images:
+ - green.png
+ code: |
+ var img = document.getElementById('green.png');
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 100, 50);
+ deferTest();
+ img.onload = t.step_func_done(function ()
+ {
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ });
+ img.src = '/images/red.png';
+ expected: green
+
+- name: 2d.pattern.modify.canvas1
+ canvasType: ['HtmlCanvas']
+ code: |
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.pattern.modify.canvas2
+ code: |
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.pattern.crosscanvas
+ images:
+ - green.png
+ code: |
+ {{ load_image }}
+
+ var pattern = {{ create_canvas }}.getContext('2d').createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+ variants:
+ _HtmlCanvas:
+ canvasType: ['HtmlCanvas']
+ load_image: var img = document.getElementById('{{ images[0] }}');
+ create_canvas: document.createElement('canvas')
+ _OffscreenCanvas:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ test_type: promise
+ load_image: |-
+ var response = await fetch('/images/{{ images[0] }}')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+ create_canvas: new OffscreenCanvas(100, 50)
+
+- name: 2d.pattern.paint.norepeat.basic
+ images:
+ - green.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.norepeat.outside
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+ ctx.fillRect(-100, 0, 100, 50);
+ ctx.fillRect(0, 50, 100, 50);
+ ctx.fillRect(100, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.norepeat.coord1
+ images:
+ - green.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.norepeat.coord2
+ images:
+ - green.png
+ code: |
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 0);
+ ctx.fillRect(-50, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.norepeat.coord3
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeat.basic
+ images:
+ - green-16x16.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeat.outside
+ images:
+ - green-16x16.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(50, 25);
+ ctx.fillRect(-50, -25, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeat.coord1
+ images:
+ - rgrg-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeat.coord2
+ images:
+ - ggrr-256x256.png
+ code: |
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeat.coord3
+ images:
+ - rgrg-256x256.png
+ code: |
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-128, -78);
+ ctx.fillRect(128, 78, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeatx.basic
+ images:
+ - green-16x16.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 16);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeatx.outside
+ images:
+ - red-16x16.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeatx.coord1
+ images:
+ - red-16x16.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat-x');
+ ctx.fillStyle = pattern;
+ ctx.translate(0, 16);
+ ctx.fillRect(0, -16, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 16);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 98,25 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeaty.basic
+ images:
+ - green-16x16.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeaty.outside
+ images:
+ - red-16x16.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.repeaty.coord1
+ images:
+ - red-16x16.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat-y');
+ ctx.fillStyle = pattern;
+ ctx.translate(48, 0);
+ ctx.fillRect(-48, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 16, 50);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.orientation.image
+ desc: Image patterns do not get flipped when painted
+ images:
+ - rrgg-256x256.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.save();
+ ctx.translate(0, -103);
+ ctx.fillRect(0, 103, 100, 50);
+ ctx.restore();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.pattern.paint.orientation.canvas
+ desc: Canvas patterns do not get flipped when painted
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 25);
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 25, 100, 25);
+
+ var pattern = ctx.createPattern(canvas2, 'no-repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 25);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.pattern.animated.gif
+ desc: createPattern() of an animated GIF draws the first frame
+ canvasType: ['HtmlCanvas']
+ images:
+ - anim-gr.gif
+ code: |
+ deferTest();
+ step_timeout(function () {
+ var pattern = ctx.createPattern(document.getElementById('anim-gr.gif'), 'repeat');
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, 0, 50, 50);
+ step_timeout(t.step_func_done(function () {
+ ctx.fillRect(50, 0, 50, 50);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ }), 250);
+ }, 250);
+ expected: green
+
+- name: 2d.fillStyle.CSSRGB
+ desc: CSSRGB works as color input
+ canvasType: ['HtmlCanvas', 'OffscreenCanvas']
+ code: |
+ ctx.fillStyle = new CSSRGB(1, 0, 1);
+ @assert ctx.fillStyle === '#ff00ff';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 255,0,255,255;
+
+ const color = new CSSRGB(0, CSS.percent(50), 0);
+ ctx.fillStyle = color;
+ @assert ctx.fillStyle === '#008000';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,128,0,255;
+ color.g = 0;
+ ctx.fillStyle = color;
+ @assert ctx.fillStyle === '#000000';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,255;
+
+ color.alpha = 0;
+ ctx.fillStyle = color;
+ @assert ctx.fillStyle === 'rgba(0, 0, 0, 0)';
+ ctx.reset();
+ color.alpha = 0.5;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,0,0,128;
+
+ ctx.fillStyle = new CSSHSL(CSS.deg(0), 1, 1).toRGB();
+ @assert ctx.fillStyle === '#ffffff';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 255,255,255,255;
+
+ color.alpha = 1;
+ color.g = 1;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+ expected: green
+
+- name: 2d.fillStyle.CSSHSL
+ desc: CSSHSL works as color input
+ canvasType: ['HtmlCanvas', 'OffscreenCanvas']
+ code: |
+ ctx.fillStyle = new CSSHSL(CSS.deg(180), 0.5, 0.5);
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ 64,191,191,255 +/- 3;
+
+ const color = new CSSHSL(CSS.deg(180), 1, 1);
+ ctx.fillStyle = color;
+ @assert ctx.fillStyle === '#ffffff';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 255,255,255,255;
+ color.l = 0.5;
+ ctx.fillStyle = color;
+ @assert ctx.fillStyle === '#00ffff';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,255,255;
+
+ ctx.fillStyle = new CSSRGB(1, 0, 1).toHSL();
+ @assert ctx.fillStyle === '#ff00ff';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 255,0,255,255;
+
+ color.h = CSS.deg(120);
+ color.s = 1;
+ color.l = 0.5;
+ ctx.fillStyle = color;
+ ctx.fillRect(0, 0, 100, 50);
+ expected: green
+
+- name: 2d.fillStyle.colormix
+ desc: color-mix works as color input
+ canvasType: ['HtmlCanvas', 'OffscreenCanvas', 'Worker']
+ code: |
+ ctx.fillStyle = "color-mix(in srgb, red, blue)";
+ @assert ctx.fillStyle === 'color(srgb 0.5 0 0.5)';
+ ctx.fillStyle = "color-mix(in srgb, red, color(srgb 1 0 0))";
+ @assert ctx.fillStyle === 'color(srgb 1 0 0)';
+
+- name: 2d.fillStyle.colormix.currentcolor
+ desc: color-mix works as color input with currentcolor
+ canvasType: ['HtmlCanvas']
+ code: |
+ canvas.setAttribute('style', 'color: magenta');
+ ctx.fillStyle = "color-mix(in srgb, black, currentcolor)";
+ @assert ctx.fillStyle === 'color(srgb 0.5 0 0.5)';
+ ctx.strokeStyle = "color-mix(in srgb, black, currentcolor)";
+ @assert ctx.strokeStyle === 'color(srgb 0.5 0 0.5)';
+
+- name: 2d.strokeStyle.colormix
+ desc: color-mix works as color input
+ canvasType: ['HtmlCanvas', 'OffscreenCanvas']
+ code: |
+ ctx.strokeStyle = "color-mix(in srgb, red, blue)";
+ @assert ctx.strokeStyle === 'color(srgb 0.5 0 0.5)';
+ ctx.strokeStyle = "color-mix(in srgb, red, color(srgb 1 0 0))";
+ @assert ctx.strokeStyle === 'color(srgb 1 0 0)';
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml
new file mode 100644
index 0000000000..01c83a33e2
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml
@@ -0,0 +1,680 @@
+- name: 2d.filter.value
+ desc: test if ctx.filter works correctly
+ code: |
+ @assert ctx.filter == 'none';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.save();
+ ctx.filter = 'none';
+ @assert ctx.filter == 'none';
+ ctx.restore();
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = 'blur(10)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'blur 10px';
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = 'inherit';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'initial';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'unset';
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = '';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = null;
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = undefined;
+ @assert ctx.filter == 'blur(5px)';
+
+ ctx.filter = 'blur( 5px)';
+ assert_equals(ctx.filter, 'blur( 5px)');
+
+- name: 2d.filter.canvasFilterObject.tentative
+ desc: Test CanvasFilter() object
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ @assert ctx.filter == 'none';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1, 2]});
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = new CanvasFilter([
+ {name: 'gaussianBlur', stdDeviation: 5},
+ {name: 'gaussianBlur', stdDeviation: 10}
+ ]);
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.filter = ctx.filter;
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'none';
+ @assert ctx.filter == 'none';
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ ctx.filter = 'this string is not a filter and should do nothing';
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+
+- name: 2d.filter.canvasFilterObject.tentative
+ desc: Test CanvasFilter() object
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ @assert ctx.filter == 'none';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1, 2]});
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = new CanvasFilter([
+ {name: 'gaussianBlur', stdDeviation: 5},
+ {name: 'gaussianBlur', stdDeviation: 10}
+ ]);
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ var canvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.filter = ctx.filter;
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+ ctx.filter = 'blur(5px)';
+ @assert ctx.filter == 'blur(5px)';
+ ctx.filter = 'none';
+ @assert ctx.filter == 'none';
+ ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 5});
+ ctx.filter = 'this string is not a filter and should do nothing';
+ @assert ctx.filter.toString() == '[object CanvasFilter]';
+
+- name: 2d.filter.canvasFilterObject.blur.exceptions.tentative
+ desc: Test exceptions on CanvasFilter() blur.object
+ code: |
+ @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur'});
+ @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined});
+ @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'});
+ @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]});
+ @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN});
+ @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}});
+
+- name: 2d.filter.canvasFilterObject.colorMatrix.tentative
+ desc: Test the functionality of ColorMatrix filters in CanvasFilter objects
+ code: |
+ @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: undefined});
+ @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: 'foo'});
+ @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: null});
+ @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]});
+ @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']});
+ @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]});
+ ctx.fillStyle = '#f00';
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 255,0,0,255;
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 0,91,0,255;
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 0,109,109,255;
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 109,18,255,255;
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 155,27,27,255;
+ ctx.clearRect(0, 0, 100, 50);
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'});
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 10,10 ==~ 0,0,0,54;
+ ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [
+ 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0
+ ]});
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 25);
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 25, 50, 25);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(50, 25, 50, 25);
+ @assert pixel 10,10 ==~ 0,255,0,255;
+ @assert pixel 60,10 ==~ 0,255,0,255;
+ @assert pixel 10,30 ==~ 0,255,0,255;
+ @assert pixel 60,30 ==~ 0,255,0,255;
+
+- name: 2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative
+ desc: Test exceptions on CanvasFilter() convolveMatrix
+ code: |
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix'});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', divisor: 2});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]});
+ @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]});
+ // This should not throw an error
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]});
+ ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]});
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with linear type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, slopes, intercepts) {
+ return [
+ Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255,
+ Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255,
+ Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255,
+ ];
+ }
+
+ const slopes = [0.5, 1.2, -0.2];
+ const intercepts = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]},
+ funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]},
+ funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, slopes, intercepts);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with identity type
+ code: |
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'identity'},
+ funcG: {type: 'identity'},
+ funcB: {type: 'identity'},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`,
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with gamma type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getColor(inputColor, amplitude, exponent, offset) {
+ return [
+ Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255,
+ Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255,
+ ];
+ }
+
+ const amplitudes = [2, 1.1, 0.5];
+ const exponents = [5, 3, 1];
+ const offsets = [0.25, 0, 0.5];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]},
+ funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]},
+ funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, amplitudes, exponents, offsets);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.table.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with table type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length - 1;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k] + (C - k/n) * n * (V[k + 1] - V[k]);
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'table', tableValues: tableValuesR},
+ funcG: {type: 'table', tableValues: tableValuesG},
+ funcB: {type: 'table', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative
+ desc: Test pixels on CanvasFilter() componentTransfer with discrete type
+ code: |
+ // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
+ function getTransformedValue(C, V) {
+ // Get the right interval
+ const n = V.length;
+ const k = C == 1 ? n - 1 : Math.floor(C * n);
+ return V[k];
+ }
+
+ function getColor(inputColor, tableValues) {
+ const result = [0, 0, 0];
+ for (const i in inputColor) {
+ const C = inputColor[i]/255;
+ const Cprime = getTransformedValue(C, tableValues[i]);
+ result[i] = Math.max(0, Math.min(1, Cprime)) * 255;
+ }
+ return result;
+ }
+
+ tableValuesR = [0, 0, 1, 1];
+ tableValuesG = [2, 0, 0.5, 3];
+ tableValuesB = [1, -1, 5, 0];
+ ctx.filter = new CanvasFilter({name: 'componentTransfer',
+ funcR: {type: 'discrete', tableValues: tableValuesR},
+ funcG: {type: 'discrete', tableValues: tableValuesG},
+ funcB: {type: 'discrete', tableValues: tableValuesB},
+ });
+
+ const inputColors = [
+ [255, 255, 255],
+ [0, 0, 0],
+ [127, 0, 34],
+ [252, 186, 3],
+ [50, 68, 87],
+ ];
+
+ for (const color of inputColors) {
+ let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]);
+ ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ ctx.fillRect(0, 0, 10, 10);
+ _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2);
+ }
+
+- name: 2d.filter.canvasFilterObject.gaussianBlur.tentative
+ desc: Test CanvasFilter() with gaussianBlur.
+ size: [100, 100]
+ code: |
+ ctx.fillStyle = 'teal';
+ ctx.filter = new CanvasFilter({
+ name: 'gaussianBlur',
+ stdDeviation: [{{ blur_x }}, {{blur_y}}],
+ });
+ ctx.fillRect(25, 25, 50, 50);
+ html_reference: |
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="{{ size[0] }}" height="{{ size[1] }}"
+ color-interpolation-filters="sRGB">
+ <filter id="blur" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="{{ blur_x }} {{blur_y}}" />
+ </filter>
+ <rect x="25" y="25" width="50" height="50"
+ fill="teal" filter="url(#blur)" />
+ </svg>
+ variants:
+ x-only:
+ blur_x: 4
+ blur_y: 0
+ mostly-x:
+ blur_x: 4
+ blur_y: 1
+ isotropic:
+ blur_x: 4
+ blur_y: 4
+ mostly-y:
+ blur_x: 1
+ blur_y: 4
+ y-only:
+ blur_x: 0
+ blur_y: 4
+
+- name: 2d.filter.canvasFilterObject.dropShadow.tentative
+ desc: Test CanvasFilter() dropShadow object.
+ size: [520, 420]
+ code: |
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(0, 0, {{ size[0] }}, 50);
+ ctx.fillRect(0, 100, {{ size[0] }}, 50);
+ ctx.fillRect(0, 200, {{ size[0] }}, 50);
+ ctx.fillRect(0, 300, {{ size[0] }}, 50);
+
+ ctx.fillStyle = 'crimson';
+
+ // Parameter defaults.
+ ctx.filter = new CanvasFilter({name: 'dropShadow'});
+ ctx.fillRect(10, 10, 80, 80);
+
+ // All parameters specified.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple', floodOpacity: 0.7});
+ ctx.fillRect(110, 10, 80, 80);
+
+ // Named color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 110, 80, 80);
+
+ // System color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'LinkText'});
+ ctx.fillRect(110, 110, 80, 80);
+
+ // Numerical color.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 1)'});
+ ctx.fillRect(210, 110, 80, 80);
+
+ // Transparent floodColor.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)'});
+ ctx.fillRect(310, 110, 80, 80);
+
+ // Transparent floodColor and floodOpacity.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3,
+ floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7});
+ ctx.fillRect(410, 110, 80, 80);
+
+ // No blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0,
+ floodColor: 'purple'});
+ ctx.fillRect(10, 210, 80, 80);
+
+ // Single float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5,
+ floodColor: 'purple'});
+ ctx.fillRect(110, 210, 80, 80);
+
+ // Single negative float blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5,
+ floodColor: 'purple'});
+ ctx.fillRect(210, 210, 80, 80);
+
+ // Two floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5],
+ floodColor: 'purple'});
+ ctx.fillRect(310, 210, 80, 80);
+
+ // Two negative floats (X&Y) blur.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5],
+ floodColor: 'purple'});
+ ctx.fillRect(410, 210, 80, 80);
+
+ // Degenerate parameter values.
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null,
+ floodColor: 'purple', floodOpacity: [2]});
+ ctx.fillRect(10, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']],
+ floodColor: 'purple', floodOpacity: '0.8'});
+ ctx.fillRect(110, 310, 80, 80);
+
+ ctx.filter = new CanvasFilter(
+ {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false,
+ floodColor: 'purple', floodOpacity: ['0.4']});
+ ctx.fillRect(210, 310, 80, 80);
+ html_reference: |
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width={{ size[0] }} height={{ size[1] }}
+ color-interpolation-filters="sRGB">
+ <rect x=0 y=0 width=100% height=50 fill="teal" />
+ <rect x=0 y=100 width=100% height=50 fill="teal" />
+ <rect x=0 y=200 width=100% height=50 fill="teal" />
+ <rect x=0 y=300 width=100% height=50 fill="teal" />
+
+ <rect x=10 y=10 width=80 height=80 fill="crimson"
+ filter="drop-shadow(2px 2px 2px black)"/>
+ <rect x=110 y=10 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 5px rgba(128, 0, 128, 0.7))"/>
+
+ <rect x=10 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px purple)"/>
+ <rect x=110 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px LinkText)"/>
+ <rect x=210 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/>
+ <rect x=310 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.7))"/>
+ <rect x=410 y=110 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.49))"/>
+
+ <rect x=10 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+ <rect x=110 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 5px purple)"/>
+ <rect x=210 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+ <filter id="separable-filter"
+ x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx=9 dy=12 stdDeviation="3 5" flood-color="purple"/>
+ </filter>
+ <rect x=310 y=210 width=80 height=80 fill="crimson"
+ filter="url(#separable-filter)"/>
+ <rect x=410 y=210 width=80 height=80 fill="crimson"
+ filter="drop-shadow(9px 12px 0px purple)"/>
+
+ <rect x=10 y=310 width=80 height=80 fill="crimson"
+ filter="drop-shadow(-5px 0px 0px purple)"/>
+ <filter id="separable-filter-degenerate"
+ x="-100%" y="-100%" width="300%" height="300%">
+ <feDropShadow dx=0 dy=5 stdDeviation="0 3"
+ flood-color="rgba(128, 0, 128, 0.8)"/>
+ </filter>
+ <rect x=110 y=310 width=80 height=80 fill="crimson"
+ filter="url(#separable-filter-degenerate)"/>
+ <rect x=210 y=310 width=80 height=80 fill="crimson"
+ filter="drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/>
+ </svg>
+
+- name: 2d.filter.canvasFilterObject.dropShadow.exceptions.tentative
+ desc: Test exceptions on CanvasFilter() dropShadow object
+ code: |
+ @unroll @assert new CanvasFilter({\-
+ name: 'dropShadow', \-
+ <dx | dy | floodOpacity>: \-
+ <10 | -1 | 0.5 | null | true | false | [] | [20] | '30'>});
+ @unroll @assert new CanvasFilter({\-
+ name: 'dropShadow', \-
+ <stdDeviation>: \-
+ <10 | -1 | 0.5 | null | true | false | [] | [20] | '30' | \-
+ [10, -1] | [0.5, null] | [true, false] | [[], [20]] | \-
+ ['30', ['40']]>});
+ @unroll @assert new CanvasFilter({\-
+ name: 'dropShadow', \-
+ <floodColor>: \-
+ <'red' | 'canvas' | 'rgba(4, -3, 0.5, 1)' | '#aabbccdd' | '#abcd'>});
+
+ @unroll @assert throws TypeError new CanvasFilter({\-
+ name: 'dropShadow', \-
+ <dx | dy | floodOpacity>: \-
+ <NaN | Infinity | -Infinity | undefined | 'test' | {} | [1, 2]>});
+ @unroll @assert throws TypeError new CanvasFilter({\-
+ name: 'dropShadow', \-
+ <stdDeviation>: \-
+ <NaN | Infinity | -Infinity | undefined | 'test' | {} | [1, 2, 3] | \-
+ [1, NaN] | [1, Infinity] | [1, -Infinity] | [1, undefined] | \-
+ [1, 'test'] | [1, {}] | [1, [2, 3]]>});
+ @unroll @assert throws TypeError new CanvasFilter({\-
+ name: 'dropShadow', \-
+ <floodColor>: \-
+ <'test' | 'rgba(NaN, 3, 2, 1)' | 10 | undefined | null | NaN>});
+
+- name: 2d.filter.canvasFilterObject.turbulence.inputTypes.tentative
+ desc: Test exceptions on CanvasFilter() turbulence object
+ code: |
+ const errorTestCases = [
+ {baseFrequency: {}},
+ {baseFrequency: -1},
+ {baseFrequency: [0, -1]},
+ {baseFrequency: NaN},
+ {baseFrequency: Infinity},
+ {baseFrequency: undefined},
+ {baseFrequency: -Infinity},
+ {baseFrequency: 'test'},
+
+ {numOctaves: {}},
+ {numOctaves: -1},
+ {numOctaves: NaN},
+ {numOctaves: Infinity},
+ {numOctaves: undefined},
+ {numOctaves: -Infinity},
+ {numOctaves: [1, 1]},
+ {numOctaves: 'test'},
+
+ {seed: {}},
+ {seed: NaN},
+ {seed: Infinity},
+ {seed: undefined},
+ {seed: -Infinity},
+ {seed: [1, 1]},
+ {seed: 'test'},
+
+ {stitchTiles: {}},
+ {stitchTiles: NaN},
+ {stitchTiles: Infinity},
+ {stitchTiles: undefined},
+ {stitchTiles: -Infinity},
+ {stitchTiles: [1, 1]},
+ {stitchTiles: 'test'},
+ {stitchTiles: null},
+ {stitchTiles: []},
+ {stitchTiles: [10]},
+ {stitchTiles: 30},
+ {stitchTiles: false},
+ {stitchTiles: true},
+ {stitchTiles: '10'},
+ {stitchTiles: -1},
+
+ {type: {}},
+ {type: NaN},
+ {type: Infinity},
+ {type: undefined},
+ {type: -Infinity},
+ {type: [1, 1]},
+ {type: 'test'},
+ {type: null},
+ {type: []},
+ {type: [10]},
+ {type: 30},
+ {type: false},
+ {type: true},
+ {type: '10'},
+ {type: -1},
+ ]
+
+ // null and [] = 0 when parsed as number
+ const workingTestCases = [
+ {baseFrequency: null},
+ {baseFrequency: []},
+ {baseFrequency: [10]},
+ {baseFrequency: [10, 3]},
+ {baseFrequency: 30},
+ {baseFrequency: false},
+ {baseFrequency: true},
+ {baseFrequency: '10'},
+
+ {numOctaves: null},
+ {numOctaves: []},
+ {numOctaves: [10]},
+ {numOctaves: 30},
+ {numOctaves: false},
+ {numOctaves: true},
+ {numOctaves: '10'},
+
+ {seed: null},
+ {seed: []},
+ {seed: [10]},
+ {seed: 30},
+ {seed: false},
+ {seed: true},
+ {seed: '10'},
+ {seed: -1},
+
+ {stitchTiles: 'stitch'},
+ {stitchTiles: 'noStitch'},
+
+ {type: 'fractalNoise'},
+ {type: 'turbulence'},
+ ]
+
+ for (testCase of errorTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ @assert throws TypeError new CanvasFilter(filterOptions);
+ }
+
+ for (testCase of workingTestCases) {
+ const filterOptions = {...{name: 'turbulence'}, ...testCase};
+ @assert new CanvasFilter(filterOptions) != null;
+ }
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml
new file mode 100644
index 0000000000..a44cb2ea2c
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml
@@ -0,0 +1,1022 @@
+- name: 2d.layer.global-states
+ desc: Checks that layers correctly use global render states.
+ size: [200, 200]
+ code: |
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ {{ render_states }}
+
+ ctx.beginLayer();
+
+ // Enable compositing in the layer to validate that draw calls in the layer
+ // won't individually composite with the background.
+ ctx.globalCompositeOperation = 'screen';
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ reference: |
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ {{ render_states }}
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.globalCompositeOperation = 'screen';
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(50, 50, 75, 50);
+ ctx2.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2.fillRect(70, 70, 75, 50);
+
+ ctx.drawImage(canvas2, 0, 0);
+ variants: &global-state-variants
+ no-global-states:
+ render_states: // No global states.
+ alpha:
+ render_states: ctx.globalAlpha = 0.6;
+ blending:
+ render_states: ctx.globalCompositeOperation = 'multiply';
+ composite:
+ render_states: ctx.globalCompositeOperation = 'source-in';
+ shadow:
+ render_states: |-
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+ alpha.blending:
+ render_states: |-
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ alpha.composite:
+ render_states: |-
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ alpha.shadow:
+ render_states: |-
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+ alpha.blending.shadow:
+ render_states: |-
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+ alpha.composite.shadow:
+ render_states: |-
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+ blending.shadow:
+ render_states: |-
+ ctx.globalCompositeOperation = 'multiply';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+ composite.shadow:
+ render_states: |-
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'rgba(255, 165, 0, 0.5)';
+ ctx.shadowBlur = 3;
+
+- name: 2d.layer.global-states.filter
+ desc: Checks that layers with filters correctly use global render states.
+ size: [200, 200]
+ code: |
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ {{ render_states }}
+
+ ctx.beginLayer({filter: [
+ {name: 'colorMatrix', values: [0.393, 0.769, 0.189, 0, 0,
+ 0.349, 0.686, 0.168, 0, 0,
+ 0.272, 0.534, 0.131, 0, 0,
+ 0, 0, 0, 1, 0]},
+ {name: 'componentTransfer',
+ funcA: {type: "table", tableValues: [0, 0.7]}},
+ {name: 'dropShadow', dx: 5, dy: 5, floodColor: '#81e'}]});
+
+ ctx.fillStyle = 'rgba(200, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 200, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ reference: |
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="{{ size[0] }}" height="{{ size[1] }}"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feColorMatrix
+ type="matrix"
+ values="0.393 0.769 0.189 0 0
+ 0.349 0.686 0.168 0 0
+ 0.272 0.534 0.131 0 0
+ 0 0 0 1 0" />
+ <feComponentTransfer>
+ <feFuncA type="table" tableValues="0 0.7"></feFuncA>
+ </feComponentTransfer>
+ <feDropShadow dx="5" dy="5" flood-color="#81e" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="75" height="50" fill="rgba(200, 0, 0, 1)"/>
+ <rect x="70" y="70" width="75" height="50" fill="rgba(0, 200, 0, 1)"/>
+ </g>
+ </svg>`;
+
+ const img = new Image();
+ img.width = {{ size[0] }};
+ img.height = {{ size[1] }};
+ img.onload = () => {
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+
+ var circle = new Path2D();
+ circle.arc(90, 90, 45, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ {{ render_states }}
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+ variants: *global-state-variants
+
+- name: 2d.layer.global-filter
+ desc: Tests that layers ignore the global context filter.
+ size: [150, 100]
+ code: |
+ ctx.filter = 'blur(5px)'
+
+ ctx.beginLayer();
+ ctx.fillRect(10, 10, 30, 30); // `ctx.filter` applied to draw call.
+ ctx.endLayer();
+
+ ctx.beginLayer();
+ ctx.filter = 'none';
+ ctx.fillRect(60, 10, 30, 30); // Should not be filted by the layer.
+ ctx.endLayer();
+
+ ctx.fillRect(110, 10, 30, 30); // `ctx.filter` is still set.
+ reference: |
+ ctx.fillRect(60, 10, 30, 30);
+ ctx.filter = 'blur(5px)'
+ ctx.fillRect(10, 10, 30, 30);
+ ctx.fillRect(110, 10, 30, 30);
+
+- name: 2d.layer.nested
+ desc: Tests nested canvas layers.
+ size: [200, 200]
+ code: |
+ var circle = new Path2D();
+ circle.arc(90, 90, 40, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(70, 70, 75, 50);
+
+ ctx.endLayer();
+ ctx.endLayer();
+ reference: |
+ var circle = new Path2D();
+ circle.arc(90, 90, 40, 0, 2 * Math.PI);
+ ctx.fill(circle);
+
+ ctx.globalCompositeOperation = 'source-in';
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+
+ ctx2.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx2.fillRect(60, 60, 75, 50);
+
+ ctx2.globalAlpha = 0.5;
+
+ canvas3 = document.createElement("canvas");
+ ctx3 = canvas3.getContext("2d");
+
+ ctx3.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx3.fillRect(50, 50, 75, 50);
+ ctx3.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx3.fillRect(70, 70, 75, 50);
+
+ ctx2.drawImage(canvas3, 0, 0);
+ ctx.drawImage(canvas2, 0, 0);
+
+
+- name: 2d.layer.restore-style
+ desc: Test that ensure layers restores style values upon endLayer.
+ size: [200, 200]
+ fuzzy: maxDifference=0-1; totalPixels=0-950
+ code: |
+ ctx.fillStyle = 'rgba(0,0,255,1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(70, 70, 75, 50);
+ reference: |
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ canvas2 = document.createElement("canvas");
+ ctx2 = canvas2.getContext("2d");
+ ctx2.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2.fillRect(60, 60, 75, 50);
+ ctx.drawImage(canvas2, 0, 0);
+
+ ctx.fillRect(70, 70, 75, 50);
+
+- name: 2d.layer.layer-rendering-state-reset-in-layer
+ desc: Tests that layers ignore the global context filter.
+ code: |
+ ctx.globalAlpha = 0.5;
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#0000ff';
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 20;
+ ctx.shadowBlur = 30;
+
+ @assert ctx.globalAlpha === 0.5;
+ @assert ctx.globalCompositeOperation === 'xor';
+ @assert ctx.shadowColor === '#0000ff';
+ @assert ctx.shadowOffsetX === 10;
+ @assert ctx.shadowOffsetY === 20;
+ @assert ctx.shadowBlur === 30;
+
+ ctx.beginLayer();
+
+ @assert ctx.globalAlpha === 1.0;
+ @assert ctx.globalCompositeOperation === 'source-over';
+ @assert ctx.shadowColor === 'rgba(0, 0, 0, 0)';
+ @assert ctx.shadowOffsetX === 0;
+ @assert ctx.shadowOffsetY === 0;
+ @assert ctx.shadowBlur === 0;
+
+ ctx.endLayer();
+
+ @assert ctx.globalAlpha === 0.5;
+ @assert ctx.globalCompositeOperation === 'xor';
+ @assert ctx.shadowColor === '#0000ff';
+ @assert ctx.shadowOffsetX === 10;
+ @assert ctx.shadowOffsetY === 20;
+ @assert ctx.shadowBlur === 30;
+
+- name: 2d.layer.clip-outside
+ desc: Check clipping set outside the layer
+ size: [100, 100]
+ code: |
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+ reference: |
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+ ctx2.endLayer();
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.drawImage(canvas2, 0, 0);
+
+- name: 2d.layer.clip-inside
+ desc: Check clipping set inside the layer
+ size: [100, 100]
+ code: |
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+ reference: |
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginPath();
+ ctx2.rect(15, 15, 70, 70);
+ ctx2.clip();
+
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx.drawImage(canvas2, 0, 0);
+ ctx.endLayer();
+
+- name: 2d.layer.clip-inside-and-outside
+ desc: Check clipping set inside and outside the layer
+ size: [100, 100]
+ code: |
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 80);
+ ctx.endLayer();
+ reference: |
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+
+ ctx2.beginPath();
+ ctx2.rect(15, 15, 70, 70);
+ ctx2.clip();
+
+ ctx2.fillStyle = 'blue';
+ ctx2.fillRect(10, 10, 80, 80);
+
+ const canvas3 = new OffscreenCanvas(200, 200);
+ const ctx3 = canvas3.getContext('2d');
+
+ ctx3.beginLayer({filter: {name: "gaussianBlur", stdDeviation: 12}});
+ ctx3.drawImage(canvas2, 0, 0);
+ ctx3.endLayer();
+
+ ctx.beginPath();
+ ctx.rect(15, 15, 70, 70);
+ ctx.clip();
+ ctx.drawImage(canvas3, 0, 0);
+
+- name: 2d.layer.flush-on-frame-presentation
+ desc: Check that layers state stack is flushed and rebuilt on frame renders.
+ size: [200, 200]
+ canvasType: ['HTMLCanvas']
+ test_type: "promise"
+ code: |
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}});
+ ctx.fillRect(40, 40, 75, 50);
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(50, 50, 75, 50);
+
+ // Force a flush and restoration of the state stack:
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ ctx.fillRect(70, 70, 75, 50);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(80, 80, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(80, 40, 75, 50);
+ reference: |
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(60, 60, 75, 50);
+ ctx.globalAlpha = 0.5;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -2, dy: 2}});
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(40, 40, 75, 50);
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(50, 50, 75, 50);
+
+ ctx.fillStyle = 'grey';
+ ctx.fillRect(70, 70, 75, 50);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(80, 80, 75, 50);
+ ctx.endLayer();
+
+ ctx.fillRect(80, 40, 75, 50);
+
+- name: 2d.layer.malformed-operations
+ desc: >-
+ Check that exceptions are thrown for operations that are malformed while
+ layers are open.
+ size: [200, 200]
+ code: |
+ {{ setup }}
+ // Shouldn't throw on its own.
+ {{ operation }};
+ // Make sure the exception isn't caused by calling the function twice.
+ {{ operation }};
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ assert_throws_dom("InvalidStateError",
+ () => {{ operation }});
+ variants:
+ createPattern:
+ operation: ctx.createPattern(canvas, 'repeat')
+ drawImage:
+ setup: |-
+ const canvas2 = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
+ const ctx2 = canvas2.getContext('2d');
+ operation: |-
+ ctx2.drawImage(canvas, 0, 0)
+ getImageData:
+ operation: ctx.getImageData(0, 0, {{ size[0] }}, {{ size[1] }})
+ putImageData:
+ setup: |-
+ const canvas2 = new OffscreenCanvas({{ size[0] }}, {{ size[1] }});
+ const ctx2 = canvas2.getContext('2d')
+ const data = ctx2.getImageData(0, 0, 1, 1);
+ operation: |-
+ ctx.putImageData(data, 0, 0)
+ toDataURL:
+ canvasType: ['HTMLCanvas']
+ operation: canvas.toDataURL()
+ transferToImageBitmap:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ operation: canvas.transferToImageBitmap()
+
+- name: 2d.layer.malformed-operations-with-promises
+ desc: >-
+ Check that exceptions are thrown for operations that are malformed while
+ layers are open.
+ size: [200, 200]
+ test_type: "promise"
+ code: |
+ // Shouldn't throw on its own.
+ await {{ operation }};
+ // Make sure the exception isn't caused by calling the function twice.
+ await {{ operation }};
+ // Calling again inside a layer should throw.
+ ctx.beginLayer();
+ await promise_rejects_dom(t, 'InvalidStateError', {{ operation }});
+ variants:
+ convertToBlob:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ operation: |-
+ canvas.convertToBlob()
+ createImageBitmap:
+ operation: createImageBitmap(canvas)
+ toBlob:
+ canvasType: ['HTMLCanvas']
+ operation: |-
+ new Promise(resolve => canvas.toBlob(resolve))
+
+- name: 2d.layer.several-complex
+ desc: >-
+ Test to ensure beginlayer works for filter, alpha and shadow, even with
+ consecutive layers.
+ size: [500, 500]
+ fuzzy: maxDifference=0-3; totalPixels=0-6318
+ code: |
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 95, 70);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'orange';
+ ctx.shadowBlur = 3
+
+ for (let i = 0; i < 5; i++) {
+ ctx.beginLayer();
+
+ ctx.fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx.fillRect(60 + i, 40 + i, 75, 50);
+ ctx.fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx.fillRect(80 + i, 60 + i, 75, 50);
+
+ ctx.endLayer();
+ }
+ reference: |
+ ctx.fillStyle = 'rgba(0, 0, 255, 1)';
+ ctx.fillRect(50, 50, 95, 70);
+
+ ctx.globalAlpha = 0.5;
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = 'orange';
+ ctx.shadowBlur = 3;
+
+ var canvas2 = [5];
+ var ctx2 = [5];
+
+ for (let i = 0; i < 5; i++) {
+ canvas2[i] = document.createElement("canvas");
+ ctx2[i] = canvas2[i].getContext("2d");
+ ctx2[i].fillStyle = 'rgba(225, 0, 0, 1)';
+ ctx2[i].fillRect(60, 40, 75, 50);
+ ctx2[i].fillStyle = 'rgba(0, 255, 0, 1)';
+ ctx2[i].fillRect(80, 60, 75, 50);
+
+ ctx.drawImage(canvas2[i], i, i);
+ }
+
+- name: 2d.layer.reset
+ desc: Checks that reset discards any pending layers.
+ code: |
+ // Global states:
+ ctx.globalAlpha = 0.3;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -3;
+ ctx.shadowOffsetY = 3;
+ ctx.shadowColor = 'rgba(0, 30, 0, 0.3)';
+ ctx.shadowBlur = 3;
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -3, dy: 3}});
+
+ // Layer states:
+ ctx.globalAlpha = 0.6;
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.shadowOffsetX = -6;
+ ctx.shadowOffsetY = 6;
+ ctx.shadowColor = 'rgba(0, 60, 0, 0.6)';
+ ctx.shadowBlur = 3;
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 75, 50);
+ reference:
+ ctx.fillRect(10, 10, 75, 50);
+
+- name: 2d.layer.clearRect.partial
+ desc: clearRect inside a layer can clear a portion of the layer content.
+ size: [100, 100]
+ code: |
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.clearRect(30, 30, 60, 30);
+ ctx.endLayer();
+ reference: |
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 10);
+ ctx.fillRect(20, 60, 80, 10);
+ ctx.fillRect(20, 20, 10, 50);
+ ctx.fillRect(90, 20, 10, 50);
+
+- name: 2d.layer.clearRect.full
+ desc: clearRect inside a layer can clear all of the layer content.
+ size: [100, 100]
+ code: |
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+ ctx.beginLayer();
+ ctx.fillStyle = 'red';
+ ctx.fillRect(20, 20, 80, 50);
+ ctx.fillStyle = 'green';
+ ctx.clearRect(0, 0, {{ size[0] }}, {{ size[1] }});
+ ctx.endLayer();
+ reference: |
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(10, 10, 80, 50);
+
+- name: 2d.layer.valid-calls
+ desc: No exception raised on {{ variant_desc }}.
+ variants:
+ save:
+ variant_desc: lone save() calls
+ code: ctx.save();
+ beginLayer:
+ variant_desc: lone beginLayer() calls
+ code: ctx.beginLayer();
+ restore:
+ variant_desc: lone restore() calls
+ code: ctx.restore();
+ save_restore:
+ variant_desc: save() + restore()
+ code: |-
+ ctx.save();
+ ctx.restore();
+ save_reset_restore:
+ variant_desc: save() + reset() + restore()
+ code: |-
+ ctx.save();
+ ctx.reset();
+ ctx.restore();
+ beginLayer-endLayer:
+ variant_desc: beginLayer() + endLayer()
+ code: |-
+ ctx.beginLayer();
+ ctx.save();
+ save-beginLayer:
+ variant_desc: save() + beginLayer()
+ code: |-
+ ctx.save();
+ ctx.beginLayer();
+ beginLayer-save:
+ variant_desc: beginLayer() + save()
+ code: |-
+ ctx.beginLayer();
+ ctx.save();
+
+- name: 2d.layer.invalid-calls
+ desc: Raises exception on {{ variant_desc }}.
+ code: |
+ assert_throws_dom("INVALID_STATE_ERR", function() {
+ {{ call_sequence | indent(2) }}
+ });
+ variants:
+ endLayer:
+ variant_desc: lone endLayer calls
+ call_sequence: ctx.endLayer();
+ save-endLayer:
+ variant_desc: save() + endLayer()
+ call_sequence: |-
+ ctx.save();
+ ctx.endLayer();
+ beginLayer-restore:
+ variant_desc: beginLayer() + restore()
+ call_sequence: |-
+ ctx.beginLayer();
+ ctx.restore();
+ save-beginLayer-restore:
+ variant_desc: save() + beginLayer() + restore()
+ call_sequence: |-
+ ctx.save();
+ ctx.beginLayer();
+ ctx.restore();
+ beginLayer-save-endLayer:
+ variant_desc: beginLayer() + save() + endLayer()
+ call_sequence: |-
+ ctx.beginLayer();
+ ctx.save();
+ ctx.endLayer();
+ beginLayer-reset-endLayer:
+ variant_desc: beginLayer() + reset() + endLayer()
+ call_sequence: |-
+ ctx.beginLayer();
+ ctx.reset();
+ ctx.endLayer();
+
+- name: 2d.layer.exceptions-are-no-op
+ desc: Checks that the context state is left unchanged if beginLayer throws.
+ code: |
+ // Get `beginLayer` to throw while parsing the filter.
+ assert_throws_js(TypeError,
+ () => ctx.beginLayer({filter: {name: 'colorMatrix',
+ values: 'foo'}}));
+ // `beginLayer` shouldn't have opened the layer, so `endLayer` should throw.
+ assert_throws_dom("InvalidStateError", () => ctx.endLayer());
+
+- name: 2d.layer.cross-layer-paths
+ desc: Checks that path defined in a layer is usable outside.
+ code: |
+ ctx.beginLayer();
+ ctx.translate(50, 0);
+ ctx.moveTo(0, 0);
+ ctx.endLayer();
+ ctx.lineTo(50, 100);
+ ctx.stroke();
+ reference:
+ ctx.moveTo(50, 0);
+ ctx.lineTo(50, 100);
+ ctx.stroke();
+
+- name: 2d.layer.beginLayer-options
+ desc: Checks beginLayer works for different option parameter values
+ code: |
+ ctx.beginLayer(); ctx.endLayer();
+ ctx.beginLayer(null); ctx.endLayer();
+ ctx.beginLayer(undefined); ctx.endLayer();
+ ctx.beginLayer([]); ctx.endLayer();
+ ctx.beginLayer({}); ctx.endLayer();
+
+ @assert throws TypeError ctx.beginLayer('');
+ @assert throws TypeError ctx.beginLayer(0);
+ @assert throws TypeError ctx.beginLayer(1);
+ @assert throws TypeError ctx.beginLayer(true);
+ @assert throws TypeError ctx.beginLayer(false);
+
+ ctx.beginLayer({filter: null}); ctx.endLayer();
+ ctx.beginLayer({filter: undefined}); ctx.endLayer();
+ ctx.beginLayer({filter: []}); ctx.endLayer();
+ ctx.beginLayer({filter: {}}); ctx.endLayer();
+ ctx.beginLayer({filter: {name: "unknown"}}); ctx.endLayer();
+ ctx.beginLayer({filter: ''}); ctx.endLayer();
+
+ // These cases don't throw TypeError since they can be casted to a
+ // DOMString.
+ ctx.beginLayer({filter: 0}); ctx.endLayer();
+ ctx.beginLayer({filter: 1}); ctx.endLayer();
+ ctx.beginLayer({filter: true}); ctx.endLayer();
+ ctx.beginLayer({filter: false}); ctx.endLayer();
+
+- name: 2d.layer.blur-from-outside-canvas
+ desc: Checks blur leaking inside from drawing outside the canvas
+ size: [200, 200]
+ code: |
+ {{ clipping }}
+
+ ctx.beginLayer({filter: [ {name: 'gaussianBlur', stdDeviation: 30} ]});
+
+ ctx.fillStyle = 'turquoise';
+ ctx.fillRect(201, 50, 100, 100);
+ ctx.fillStyle = 'indigo';
+ ctx.fillRect(50, 201, 100, 100);
+ ctx.fillStyle = 'orange';
+ ctx.fillRect(-1, 50, -100, 100);
+ ctx.fillStyle = 'brown';
+ ctx.fillRect(50, -1, 100, -100);
+
+ ctx.endLayer();
+ reference: |
+ const svg = `
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="{{ size[0] }}" height="{{ size[1] }}"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ <feGaussianBlur in="SourceGraphic" stdDeviation="30" />
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="201" y="50" width="100" height="100" fill="turquoise"/>
+ <rect x="50" y="201" width="100" height="100" fill="indigo"/>
+ <rect x="-101" y="50" width="100" height="100" fill="orange"/>
+ <rect x="50" y="-101" width="100" height="100" fill="brown"/>
+ </g>
+ </svg>`;
+ const img = new Image();
+ img.width = {{ size[0] }};
+ img.height = {{ size[1] }};
+ img.onload = () => {
+ {{ clipping | indent(4) }}
+
+ ctx.drawImage(img, 0, 0);
+ };
+ img.src = 'data:image/svg+xml;base64,' + btoa(svg);
+ variants:
+ no-clipping:
+ clipping: // No clipping.
+ with-clipping:
+ clipping: |-
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+- name: 2d.layer.shadow-from-outside-canvas
+ desc: Checks shadow produced by object drawn outside the canvas
+ size: [200, 200]
+ code: |
+ {{ distance }}
+
+ {{ clipping }}
+
+ ctx.beginLayer({filter: [
+ {name: 'dropShadow', dx: -({{ size[0] }} + delta),
+ dy: -({{ size[1] }} + delta), stdDeviation: 0,
+ floodColor: 'green'},
+ ]});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect({{ size[0] }} + delta, {{ size[1] }} + delta, 100, 100);
+
+ ctx.endLayer();
+ reference: |
+ {{ distance }}
+
+ {{ clipping }}
+
+ ctx.fillStyle = 'green';
+ ctx.fillRect(0, 0, 100, 100);
+ variants:
+ short-distance:
+ distance: |-
+ const delta = 1;
+ clipping: // No clipping.
+ short-distance-with-clipping:
+ distance: |-
+ const delta = 1;
+ clipping: |-
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+ long-distance:
+ distance: |-
+ const delta = 10000;
+ clipping: // No clipping.
+ long-distance-with-clipping:
+ distance: |-
+ const delta = 10000;
+ clipping: |-
+ const clipRegion = new Path2D();
+ clipRegion.rect(20, 20, 160, 160);
+ ctx.clip(clipRegion);
+
+- name: 2d.layer.opaque-canvas
+ desc: Checks that layer blending works inside opaque canvas
+ size: [300, 300]
+ code: |
+ {% if canvas_type == 'htmlcanvas' %}
+ const canvas2 = document.createElement('canvas');
+ canvas2.width = 200;
+ canvas2.height = 200;
+ {% else %}
+ const canvas2 = new OffscreenCanvas(200, 200);
+ {% endif %}
+ const ctx2 = canvas2.getContext('2d', {alpha: false});
+
+ ctx2.fillStyle = 'purple';
+ ctx2.fillRect(10, 10, 100, 100);
+
+ ctx2.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: 10,
+ stdDeviation: 0,
+ floodColor: 'rgba(200, 100, 50, 0.5)'}});
+ ctx2.fillStyle = 'green';
+ ctx2.fillRect(50, 50, 100, 100);
+ ctx2.globalAlpha = 0.8;
+ ctx2.fillStyle = 'yellow';
+ ctx2.fillRect(75, 25, 100, 100);
+ ctx2.endLayer();
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 300, 300);
+ ctx.drawImage(canvas2, 0, 0);
+ reference: |
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(0, 0, 300, 300);
+
+ ctx.fillStyle = 'black';
+ ctx.fillRect(0, 0, 200, 200);
+
+ ctx.fillStyle = 'purple';
+ ctx.fillRect(10, 10, 100, 100);
+
+ const canvas2 = new OffscreenCanvas(200, 200);
+ const ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = 'green';
+ ctx2.fillRect(50, 50, 100, 100);
+ ctx2.globalAlpha = 0.8;
+ ctx2.fillStyle = 'yellow';
+ ctx2.fillRect(75, 25, 100, 100);
+
+ ctx.shadowColor = 'rgba(200, 100, 50, 0.5)';
+ ctx.shadowOffsetX = -10;
+ ctx.shadowOffsetY = 10;
+ ctx.drawImage(canvas2, 0, 0);
+
+- name: 2d.layer.css-filters
+ desc: Checks that beginLayer works with a CSS filter string as input.
+ size: [200, 200]
+ code: &filter-test-code |
+ ctx.beginLayer({filter: {{ ctx_filter }}});
+
+ ctx.fillStyle = 'teal';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+ html_reference: &filter-test-reference |
+ <svg xmlns="http://www.w3.org/2000/svg"
+ width="{{ size[0] }}" height="{{ size[1] }}"
+ color-interpolation-filters="sRGB">
+ <filter id="filter" x="-100%" y="-100%" width="300%" height="300%">
+ {{ svg_filter | indent(4) }}
+ </filter>
+ <g filter="url(#filter)">
+ <rect x="50" y="50" width="100" height="100" fill="teal"/>
+ </g>
+ </svg>
+ variants:
+ blur:
+ ctx_filter: |-
+ 'blur(10px)'
+ svg_filter: |-
+ <feGaussianBlur stdDeviation="10" />
+ shadow:
+ ctx_filter: |-
+ 'drop-shadow(-10px -10px 5px purple)'
+ svg_filter: |-
+ <feDropShadow dx="-10" dy="-10" stdDeviation="5" flood-color="purple" />
+ blur-and-shadow:
+ ctx_filter: |-
+ 'blur(5px) drop-shadow(10px 10px 5px orange)'
+ svg_filter: |-
+ <feGaussianBlur stdDeviation="5" />
+ <feDropShadow dx="10" dy="10" stdDeviation="5" flood-color="orange" />
+
+- name: 2d.layer.anisotropic-blur
+ desc: Checks that layers allow gaussian blur with separate X and Y components.
+ size: [200, 200]
+ code: *filter-test-code
+ html_reference: *filter-test-reference
+ variants:
+ x-only:
+ ctx_filter: |-
+ { name: 'gaussianBlur', stdDeviation: [4, 0] }
+ svg_filter: |-
+ <feGaussianBlur stdDeviation="4 0" />
+ mostly-x:
+ ctx_filter: |-
+ { name: 'gaussianBlur', stdDeviation: [4, 1] }
+ svg_filter: |-
+ <feGaussianBlur stdDeviation="4 1" />
+ isotropic:
+ ctx_filter: |-
+ { name: 'gaussianBlur', stdDeviation: [4, 4] }
+ svg_filter: |-
+ <feGaussianBlur stdDeviation="4 4" />
+ mostly-y:
+ ctx_filter: |-
+ { name: 'gaussianBlur', stdDeviation: [1, 4] }
+ svg_filter: |-
+ <feGaussianBlur stdDeviation="1 4" />
+ y-only:
+ ctx_filter: |-
+ { name: 'gaussianBlur', stdDeviation: [0, 4] }
+ svg_filter: |-
+ <feGaussianBlur stdDeviation="0 4" />
+
+- name: 2d.layer.nested-filters
+ desc: Checks that nested layers work properly when both apply filters.
+ size: [400, 200]
+ code: |
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -20, dy: -20,
+ stdDeviation: 0, floodColor: 'yellow'}});
+ ctx.beginLayer({filter: 'drop-shadow(-10px -10px 0 blue)'});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+
+ ctx.beginLayer({filter: 'drop-shadow(20px 20px 0 blue)'});
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: 10, dy: 10,
+ stdDeviation: 0, floodColor: 'yellow'}});
+
+ ctx.fillStyle = 'red';
+ ctx.fillRect(250, 50, 100, 100);
+
+ ctx.endLayer();
+ ctx.endLayer();
+ reference: |
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(20, 20, 100, 100);
+ ctx.fillRect(30, 30, 100, 100);
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(40, 40, 100, 100);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(50, 50, 100, 100);
+
+ ctx.fillStyle = 'blue';
+ ctx.fillRect(280, 80, 100, 100);
+ ctx.fillRect(270, 70, 100, 100);
+ ctx.fillStyle = 'yellow';
+ ctx.fillRect(260, 60, 100, 100);
+ ctx.fillStyle = 'red';
+ ctx.fillRect(250, 50, 100, 100);
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/line-styles.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/line-styles.yaml
new file mode 100644
index 0000000000..47bf3af97e
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/line-styles.yaml
@@ -0,0 +1,954 @@
+- name: 2d.line.defaults
+ code: |
+ @assert ctx.lineWidth === 1;
+ @assert ctx.lineCap === 'butt';
+ @assert ctx.lineJoin === 'miter';
+ @assert ctx.miterLimit === 10;
+
+- name: 2d.line.width.basic
+ desc: lineWidth determines the width of line strokes
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 20;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ @assert pixel 14,25 == 0,255,0,255;
+ @assert pixel 15,25 == 0,255,0,255;
+ @assert pixel 16,25 == 0,255,0,255;
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 34,25 == 0,255,0,255;
+ @assert pixel 35,25 == 0,255,0,255;
+ @assert pixel 36,25 == 0,255,0,255;
+
+ @assert pixel 64,25 == 0,255,0,255;
+ @assert pixel 65,25 == 0,255,0,255;
+ @assert pixel 66,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ @assert pixel 84,25 == 0,255,0,255;
+ @assert pixel 85,25 == 0,255,0,255;
+ @assert pixel 86,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.width.transformed
+ desc: Line stroke widths are affected by scale transformations
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 4;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.save();
+ ctx.scale(5, 1);
+ ctx.beginPath();
+ ctx.moveTo(5, 15);
+ ctx.lineTo(5, 35);
+ ctx.stroke();
+ ctx.restore();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.save();
+ ctx.scale(-5, 1);
+ ctx.beginPath();
+ ctx.moveTo(-15, 15);
+ ctx.lineTo(-15, 35);
+ ctx.stroke();
+ ctx.restore();
+ ctx.fillRect(65, 15, 20, 20);
+
+ @assert pixel 14,25 == 0,255,0,255;
+ @assert pixel 15,25 == 0,255,0,255;
+ @assert pixel 16,25 == 0,255,0,255;
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 34,25 == 0,255,0,255;
+ @assert pixel 35,25 == 0,255,0,255;
+ @assert pixel 36,25 == 0,255,0,255;
+
+ @assert pixel 64,25 == 0,255,0,255;
+ @assert pixel 65,25 == 0,255,0,255;
+ @assert pixel 66,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ @assert pixel 84,25 == 0,255,0,255;
+ @assert pixel 85,25 == 0,255,0,255;
+ @assert pixel 86,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.width.scaledefault
+ desc: Default lineWidth strokes are affected by scale transformations
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(50, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.moveTo(0, 0.5);
+ ctx.lineTo(2, 0.5);
+ ctx.stroke();
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ @assert pixel 50,5 == 0,255,0,255;
+ @assert pixel 50,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.width.valid
+ desc: Setting lineWidth to valid values works
+ code: |
+ ctx.lineWidth = 1.5;
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = "1e1";
+ @assert ctx.lineWidth === 10;
+
+ ctx.lineWidth = 1/1024;
+ @assert ctx.lineWidth === 1/1024;
+
+ ctx.lineWidth = 1000;
+ @assert ctx.lineWidth === 1000;
+
+- name: 2d.line.width.invalid
+ desc: Setting lineWidth to invalid values is ignored
+ code: |
+ ctx.lineWidth = 1.5;
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 0;
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -1;
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = Infinity;
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -Infinity;
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = NaN;
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 'string';
+ @assert ctx.lineWidth === 1.5;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = true;
+ @assert ctx.lineWidth === 1;
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = false;
+ @assert ctx.lineWidth === 1.5;
+
+- name: 2d.line.cap.butt
+ desc: lineCap 'butt' is rendered correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'butt';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ @assert pixel 25,14 == 0,255,0,255;
+ @assert pixel 25,15 == 0,255,0,255;
+ @assert pixel 25,16 == 0,255,0,255;
+ @assert pixel 25,34 == 0,255,0,255;
+ @assert pixel 25,35 == 0,255,0,255;
+ @assert pixel 25,36 == 0,255,0,255;
+
+ @assert pixel 75,14 == 0,255,0,255;
+ @assert pixel 75,15 == 0,255,0,255;
+ @assert pixel 75,16 == 0,255,0,255;
+ @assert pixel 75,34 == 0,255,0,255;
+ @assert pixel 75,35 == 0,255,0,255;
+ @assert pixel 75,36 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.cap.round
+ desc: lineCap 'round' is rendered correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineCap = 'round';
+ ctx.lineWidth = 20;
+
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(35-tol, 15);
+ ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
+ ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(85+tol, 15);
+ ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
+ ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
+ ctx.fill();
+
+ @assert pixel 17,6 == 0,255,0,255;
+ @assert pixel 25,6 == 0,255,0,255;
+ @assert pixel 32,6 == 0,255,0,255;
+ @assert pixel 17,43 == 0,255,0,255;
+ @assert pixel 25,43 == 0,255,0,255;
+ @assert pixel 32,43 == 0,255,0,255;
+
+ @assert pixel 67,6 == 0,255,0,255;
+ @assert pixel 75,6 == 0,255,0,255;
+ @assert pixel 82,6 == 0,255,0,255;
+ @assert pixel 67,43 == 0,255,0,255;
+ @assert pixel 75,43 == 0,255,0,255;
+ @assert pixel 82,43 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.cap.square
+ desc: lineCap 'square' is rendered correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 5, 20, 40);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 5, 20, 40);
+
+ @assert pixel 25,4 == 0,255,0,255;
+ @assert pixel 25,5 == 0,255,0,255;
+ @assert pixel 25,6 == 0,255,0,255;
+ @assert pixel 25,44 == 0,255,0,255;
+ @assert pixel 25,45 == 0,255,0,255;
+ @assert pixel 25,46 == 0,255,0,255;
+
+ @assert pixel 75,4 == 0,255,0,255;
+ @assert pixel 75,5 == 0,255,0,255;
+ @assert pixel 75,6 == 0,255,0,255;
+ @assert pixel 75,44 == 0,255,0,255;
+ @assert pixel 75,45 == 0,255,0,255;
+ @assert pixel 75,46 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.cap.open
+ desc: Line caps are drawn at the corners of an unclosed rectangle
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.lineTo(200, 200);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.cap.closed
+ desc: Line caps are not drawn at the corners of an unclosed rectangle
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.closePath();
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.cap.valid
+ desc: Setting lineCap to valid values works
+ code: |
+ ctx.lineCap = 'butt'
+ @assert ctx.lineCap === 'butt';
+
+ ctx.lineCap = 'round';
+ @assert ctx.lineCap === 'round';
+
+ ctx.lineCap = 'square';
+ @assert ctx.lineCap === 'square';
+
+- name: 2d.line.cap.invalid
+ desc: Setting lineCap to invalid values is ignored
+ code: |
+ ctx.lineCap = 'butt'
+ @assert ctx.lineCap === 'butt';
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'invalid';
+ @assert ctx.lineCap === 'butt';
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'ROUND';
+ @assert ctx.lineCap === 'butt';
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round\0';
+ @assert ctx.lineCap === 'butt';
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round ';
+ @assert ctx.lineCap === 'butt';
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = "";
+ @assert ctx.lineCap === 'butt';
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'bevel';
+ @assert ctx.lineCap === 'butt';
+
+- name: 2d.line.fill.noop
+ desc: Filling a line draws nothing
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 20;
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(90, 30);
+ ctx.fill();
+ @assert pixel 50,24 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 50,26 == 0,255,0,255;
+
+- name: 2d.line.join.bevel
+ desc: lineJoin 'bevel' is rendered correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.lineTo(40-tol, 20);
+ ctx.lineTo(30, 10+tol);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.lineTo(90+tol, 20);
+ ctx.lineTo(80, 10-tol);
+ ctx.fill();
+
+ @assert pixel 34,16 == 0,255,0,255;
+ @assert pixel 34,15 == 0,255,0,255;
+ @assert pixel 35,15 == 0,255,0,255;
+ @assert pixel 36,15 == 0,255,0,255;
+ @assert pixel 36,14 == 0,255,0,255;
+
+ @assert pixel 84,16 == 0,255,0,255;
+ @assert pixel 84,15 == 0,255,0,255;
+ @assert pixel 85,15 == 0,255,0,255;
+ @assert pixel 86,15 == 0,255,0,255;
+ @assert pixel 86,14 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.join.round
+ desc: lineJoin 'round' is rendered correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'round';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ @assert pixel 36,14 == 0,255,0,255;
+ @assert pixel 36,13 == 0,255,0,255;
+ @assert pixel 37,13 == 0,255,0,255;
+ @assert pixel 38,13 == 0,255,0,255;
+ @assert pixel 38,12 == 0,255,0,255;
+
+ @assert pixel 86,14 == 0,255,0,255;
+ @assert pixel 86,13 == 0,255,0,255;
+ @assert pixel 87,13 == 0,255,0,255;
+ @assert pixel 88,13 == 0,255,0,255;
+ @assert pixel 88,12 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.join.miter
+ desc: lineJoin 'miter' is rendered correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 30, 20);
+ ctx.fillRect(20, 10, 20, 30);
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 30, 20);
+ ctx.fillRect(70, 10, 20, 30);
+
+ @assert pixel 38,12 == 0,255,0,255;
+ @assert pixel 39,11 == 0,255,0,255;
+ @assert pixel 40,10 == 0,255,0,255;
+ @assert pixel 41,9 == 0,255,0,255;
+ @assert pixel 42,8 == 0,255,0,255;
+
+ @assert pixel 88,12 == 0,255,0,255;
+ @assert pixel 89,11 == 0,255,0,255;
+ @assert pixel 90,10 == 0,255,0,255;
+ @assert pixel 91,9 == 0,255,0,255;
+ @assert pixel 92,8 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.join.open
+ desc: Line joins are not drawn at the corner of an unclosed rectangle
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.join.closed
+ desc: Line joins are drawn at the corner of a closed rectangle
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.closePath();
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.join.parallel
+ desc: Line joins are drawn at 180-degree joins
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 300;
+ ctx.lineJoin = 'round';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(-100, 25);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.join.valid
+ desc: Setting lineJoin to valid values works
+ code: |
+ ctx.lineJoin = 'bevel'
+ @assert ctx.lineJoin === 'bevel';
+
+ ctx.lineJoin = 'round';
+ @assert ctx.lineJoin === 'round';
+
+ ctx.lineJoin = 'miter';
+ @assert ctx.lineJoin === 'miter';
+
+- name: 2d.line.join.invalid
+ desc: Setting lineJoin to invalid values is ignored
+ code: |
+ ctx.lineJoin = 'bevel'
+ @assert ctx.lineJoin === 'bevel';
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'invalid';
+ @assert ctx.lineJoin === 'bevel';
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'ROUND';
+ @assert ctx.lineJoin === 'bevel';
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round\0';
+ @assert ctx.lineJoin === 'bevel';
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round ';
+ @assert ctx.lineJoin === 'bevel';
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = "";
+ @assert ctx.lineJoin === 'bevel';
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'butt';
+ @assert ctx.lineJoin === 'bevel';
+
+- name: 2d.line.miter.exceeded
+ desc: Miter joins are not drawn when the miter limit is exceeded
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.miter.acute
+ desc: Miter joins are drawn correctly with acute angles
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 2.614;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 2.613;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.miter.obtuse
+ desc: Miter joins are drawn correctly with obtuse angles
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 1600;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.083;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.082;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.miter.rightangle
+ desc: Miter joins are not drawn when the miter limit is exceeded, on exact right
+ angles
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 200);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.miter.lineedge
+ desc: Miter joins are not drawn when the miter limit is exceeded at the corners
+ of a zero-height rectangle
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.strokeRect(100, 25, 200, 0);
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.miter.within
+ desc: Miter joins are drawn when the miter limit is not quite exceeded
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.416;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.miter.valid
+ desc: Setting miterLimit to valid values works
+ code: |
+ ctx.miterLimit = 1.5;
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = "1e1";
+ @assert ctx.miterLimit === 10;
+
+ ctx.miterLimit = 1/1024;
+ @assert ctx.miterLimit === 1/1024;
+
+ ctx.miterLimit = 1000;
+ @assert ctx.miterLimit === 1000;
+
+- name: 2d.line.miter.invalid
+ desc: Setting miterLimit to invalid values is ignored
+ code: |
+ ctx.miterLimit = 1.5;
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 0;
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -1;
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = Infinity;
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -Infinity;
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = NaN;
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 'string';
+ @assert ctx.miterLimit === 1.5;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = true;
+ @assert ctx.miterLimit === 1;
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = false;
+ @assert ctx.miterLimit === 1.5;
+
+- name: 2d.line.cross
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(110, 50);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(100, 60);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.union
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 24);
+ ctx.lineTo(100, 25);
+ ctx.lineTo(0, 26);
+ ctx.closePath();
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 25,1 == 0,255,0,255;
+ @assert pixel 48,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 25,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.line.invalid.strokestyle
+ desc: Verify correct behavior of canvas on an invalid strokeStyle()
+ code: |
+ ctx.strokeStyle = 'rgb(0, 255, 0)';
+ ctx.strokeStyle = 'nonsense';
+ ctx.lineWidth = 200;
+ ctx.moveTo(0,100);
+ ctx.lineTo(200,100);
+ ctx.stroke();
+ var imageData = ctx.getImageData(0, 0, 200, 200);
+ var imgdata = imageData.data;
+ @assert imgdata[4] == 0;
+ @assert imgdata[5] == 255;
+ @assert imgdata[6] == 0;
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/path-objects.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/path-objects.yaml
new file mode 100644
index 0000000000..b1754b9495
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/path-objects.yaml
@@ -0,0 +1,3403 @@
+- name: 2d.path.initial
+ #mozilla: { bug: TODO }
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.beginPath
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.moveTo.basic
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 10, 50);
+ ctx.moveTo(100, 0);
+ ctx.lineTo(10, 0);
+ ctx.lineTo(10, 50);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 90,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.moveTo.newsubpath
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.moveTo(100, 0);
+ ctx.moveTo(100, 50);
+ ctx.moveTo(0, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.moveTo.multiple
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 25);
+ ctx.moveTo(100, 25);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.moveTo.nonfinite
+ desc: moveTo() with Infinity/NaN is ignored
+ code: |
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.moveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.closePath.empty
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.closePath.newline
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.closePath();
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.closePath.nextpoint
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -1000);
+ ctx.closePath();
+ ctx.lineTo(1000, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.lineTo.ensuresubpath.1
+ desc: If there is no subpath, the point is added and nothing is drawn
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.lineTo.ensuresubpath.2
+ desc: If there is no subpath, the point is added and used for subsequent drawing
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.lineTo.basic
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.lineTo.nextpoint
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.lineTo.nonfinite
+ desc: lineTo() with Infinity/NaN is ignored
+ code: |
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.lineTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.lineTo.nonfinite.details
+ desc: lineTo() with Infinity/NaN for first arg still converts the second arg
+ code: |
+ for (var arg1 of [Infinity, -Infinity, NaN]) {
+ var converted = false;
+ ctx.lineTo(arg1, { valueOf: function() { converted = true; return 0; } });
+ @assert converted;
+ }
+ expected: clear
+
+- name: 2d.path.quadraticCurveTo.ensuresubpath.1
+ desc: If there is no subpath, the first control point is added (and nothing is drawn
+ up to it)
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(100, 50, 200, 50);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 95,45 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.quadraticCurveTo.ensuresubpath.2
+ desc: If there is no subpath, the first control point is added
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(0, 25, 100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 5,45 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.quadraticCurveTo.basic
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.quadraticCurveTo(100, 25, 100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.quadraticCurveTo.shape
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-1000, 1050);
+ ctx.quadraticCurveTo(0, -1000, 1200, 1050);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.quadraticCurveTo.scaled
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-1, 1.05);
+ ctx.quadraticCurveTo(0, -1, 1.2, 1.05);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.quadraticCurveTo.nonfinite
+ desc: quadraticCurveTo() with Infinity/NaN is ignored
+ code: |
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.quadraticCurveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.bezierCurveTo.ensuresubpath.1
+ desc: If there is no subpath, the first control point is added (and nothing is drawn
+ up to it)
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(100, 50, 200, 50, 200, 50);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 95,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.bezierCurveTo.ensuresubpath.2
+ desc: If there is no subpath, the first control point is added
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(0, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 5,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.bezierCurveTo.basic
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.bezierCurveTo.shape
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-2000, 3100);
+ ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.bezierCurveTo.scaled
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-2, 3.1);
+ ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.bezierCurveTo.nonfinite
+ desc: bezierCurveTo() with Infinity/NaN is ignored
+ code: |
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.bezierCurveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.ensuresubpath.1
+ desc: If there is no subpath, the first control point is added (and nothing is drawn
+ up to it)
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arcTo(100, 50, 200, 50, 0.1);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.ensuresubpath.2
+ desc: If there is no subpath, the first control point is added
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arcTo(0, 25, 50, 250, 0.1); // adds (x1,y1), draws nothing
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.coincide.1
+ desc: arcTo() has no effect if P0 = P1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(0, 25, 50, 1000, 1);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 100, 25, 1);
+ ctx.stroke();
+
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 50,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.coincide.2
+ desc: arcTo() draws a straight line to P1 if P1 = P2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 25, 1);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.collinear.1
+ desc: arcTo() with all points on a line, and P1 between P0/P2, draws a straight
+ line to P1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 200, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, 100, 25, 1);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.collinear.2
+ desc: arcTo() with all points on a line, and P2 between P0/P1, draws a straight
+ line to P1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 10, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 110, 25, 1);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.collinear.3
+ desc: arcTo() with all points on a line, and P0 between P1/P2, draws a straight
+ line to P1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 0, 25, 1);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, -200, 25, 1);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.shape.curve1
+ desc: arcTo() curves in the right kind of shape
+ code: |
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 55,19 == 0,255,0,255;
+ @assert pixel 55,20 == 0,255,0,255;
+ @assert pixel 55,21 == 0,255,0,255;
+ @assert pixel 64,22 == 0,255,0,255;
+ @assert pixel 65,21 == 0,255,0,255;
+ @assert pixel 72,28 == 0,255,0,255;
+ @assert pixel 73,27 == 0,255,0,255;
+ @assert pixel 78,36 == 0,255,0,255;
+ @assert pixel 79,35 == 0,255,0,255;
+ @assert pixel 80,44 == 0,255,0,255;
+ @assert pixel 80,45 == 0,255,0,255;
+ @assert pixel 80,46 == 0,255,0,255;
+ @assert pixel 65,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.shape.curve2
+ desc: arcTo() curves in the right kind of shape
+ code: |
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 55,19 == 0,255,0,255;
+ @assert pixel 55,20 == 0,255,0,255;
+ @assert pixel 55,21 == 0,255,0,255;
+ @assert pixel 64,22 == 0,255,0,255;
+ @assert pixel 65,21 == 0,255,0,255;
+ @assert pixel 72,28 == 0,255,0,255;
+ @assert pixel 73,27 == 0,255,0,255;
+ @assert pixel 78,36 == 0,255,0,255;
+ @assert pixel 79,35 == 0,255,0,255;
+ @assert pixel 80,44 == 0,255,0,255;
+ @assert pixel 80,45 == 0,255,0,255;
+ @assert pixel 80,46 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.shape.start
+ desc: arcTo() draws a straight line from P0 to P1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(200, 25, 200, 50, 10);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.shape.end
+ desc: arcTo() does not draw anything from P1 to P2
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.arcTo(-100, 25, 200, 25, 10);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.negative
+ desc: arcTo() with negative radius throws an exception
+ code: |
+ @assert throws INDEX_SIZE_ERR ctx.arcTo(0, 0, 0, 0, -1);
+ var path = new Path2D();
+ @assert throws INDEX_SIZE_ERR path.arcTo(10, 10, 20, 20, -5);
+
+- name: 2d.path.arcTo.zero.1
+ desc: arcTo() with zero radius draws a straight line from P0 to P1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 100, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(0, -25);
+ ctx.arcTo(50, -25, 50, 50, 0);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.zero.2
+ desc: arcTo() with zero radius draws a straight line from P0 to P1, even when all
+ points are collinear
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 50, 25, 0);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.transformation
+ desc: arcTo joins up to the last subpath point correctly
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-100, 0);
+ ctx.fill();
+
+ @assert pixel 0,0 == 0,255,0,255;
+ @assert pixel 50,0 == 0,255,0,255;
+ @assert pixel 99,0 == 0,255,0,255;
+ @assert pixel 0,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 99,25 == 0,255,0,255;
+ @assert pixel 0,49 == 0,255,0,255;
+ @assert pixel 50,49 == 0,255,0,255;
+ @assert pixel 99,49 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.scale
+ desc: arcTo scales the curve, not just the control points
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.scale(0.1, 1);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-1000, 0);
+ ctx.fill();
+
+ @assert pixel 0,0 == 0,255,0,255;
+ @assert pixel 50,0 == 0,255,0,255;
+ @assert pixel 99,0 == 0,255,0,255;
+ @assert pixel 0,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 99,25 == 0,255,0,255;
+ @assert pixel 0,49 == 0,255,0,255;
+ @assert pixel 50,49 == 0,255,0,255;
+ @assert pixel 99,49 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arcTo.nonfinite
+ desc: arcTo() with Infinity/NaN is ignored
+ code: |
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.arcTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,45 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.path.arc.empty
+ desc: arc() with an empty path does not draw a straight line to the start point
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.nonempty
+ desc: arc() with a non-empty path does draw a straight line to the start point
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.end
+ desc: arc() adds the end point of the arc to the subpath
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(-100, 0);
+ ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.default
+ desc: arc() with missing last argument defaults to clockwise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -Math.PI, Math.PI/2);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.angle.1
+ desc: arc() draws pi/2 .. -pi anticlockwise correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.angle.2
+ desc: arc() draws -3pi/2 .. -pi anticlockwise correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.angle.3
+ desc: arc() wraps angles mod 2pi when anticlockwise and end > start+2pi
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.angle.4
+ desc: arc() draws a full circle when clockwise and end > start+2pi
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.angle.5
+ desc: arc() wraps angles mod 2pi when clockwise and start > end+2pi
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.angle.6
+ desc: arc() draws a full circle when anticlockwise and start > end+2pi
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true);
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.zero.1
+ desc: arc() draws nothing when startAngle = endAngle and anticlockwise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, true);
+ ctx.stroke();
+ @assert pixel 50,20 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.zero.2
+ desc: arc() draws nothing when startAngle = endAngle and clockwise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, false);
+ ctx.stroke();
+ @assert pixel 50,20 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.twopie.1
+ desc: arc() draws nothing when end = start + 2pi-e and anticlockwise
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true);
+ ctx.stroke();
+ @assert pixel 50,20 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.twopie.2
+ desc: arc() draws a full circle when end = start + 2pi-e and clockwise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false);
+ ctx.stroke();
+ @assert pixel 50,20 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.twopie.3
+ desc: arc() draws a full circle when end = start + 2pi+e and anticlockwise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true);
+ ctx.stroke();
+ @assert pixel 50,20 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.twopie.4
+ desc: arc() draws nothing when end = start + 2pi+e and clockwise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false);
+ ctx.stroke();
+ @assert pixel 50,20 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.twopie.5
+ desc: arc() draws correctly when start = 2 and end = start + 2pi+e and clockwise
+ code: |
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 2, 2 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ @assert pixel 95,25 == 0,0,0,255;
+
+- name: 2d.path.arc.twopie.6
+ desc: arc() draws correctly when start = 5 and end = start + 2pi+e and clockwise
+ code: |
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 50, 5, 5 + 2*Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ @assert pixel 5,25 == 0,0,0,255;
+
+- name: 2d.path.arc.shape.1
+ desc: arc() from 0 to pi does not draw anything in the wrong half
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, false);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 20,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.shape.2
+ desc: arc() from 0 to pi draws stuff in the right half
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, true);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 20,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.shape.3
+ desc: arc() from 0 to -pi/2 does not draw anything in the wrong quadrant
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(0, 50, 50, 0, -Math.PI/2, false);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255; @moz-todo
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.shape.4
+ desc: arc() from 0 to -pi/2 draws stuff in the right quadrant
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 150;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 100, 0, -Math.PI/2, true);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.shape.5
+ desc: arc() from 0 to 5pi does not draw crazy things
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(300, 0, 100, 0, 5*Math.PI, false);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.selfintersect.1
+ desc: arc() with lineWidth > 2*radius is drawn sensibly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(100, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ @assert pixel 1,1 == 0,255,0,255; @moz-todo
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.selfintersect.2
+ desc: arc() with lineWidth > 2*radius is drawn sensibly
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 180;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(100, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,10 == 0,255,0,255;
+ @assert pixel 97,1 == 0,255,0,255;
+ @assert pixel 97,2 == 0,255,0,255;
+ @assert pixel 97,3 == 0,255,0,255;
+ @assert pixel 2,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.negative
+ desc: arc() with negative radius throws INDEX_SIZE_ERR
+ code: |
+ @assert throws INDEX_SIZE_ERR ctx.arc(0, 0, -1, 0, 0, true);
+ var path = new Path2D();
+ @assert throws INDEX_SIZE_ERR path.arc(10, 10, -5, 0, 1, false);
+
+- name: 2d.path.arc.zeroradius
+ desc: arc() with zero radius draws a line to the start point
+ code: |
+ ctx.fillStyle = '#f00'
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 0, 0, Math.PI, true);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.scale.1
+ desc: Non-uniformly scaled arcs are the right shape
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(2, 0.5);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(25, 50, 56, 0, 2*Math.PI, false);
+ ctx.fill();
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-25, 50);
+ ctx.arc(-25, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(75, 50);
+ ctx.arc(75, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, -25);
+ ctx.arc(25, -25, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, 125);
+ ctx.arc(25, 125, 24, 0, 2*Math.PI, false);
+ ctx.fill();
+
+ @assert pixel 0,0 == 0,255,0,255;
+ @assert pixel 50,0 == 0,255,0,255;
+ @assert pixel 99,0 == 0,255,0,255;
+ @assert pixel 0,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 99,25 == 0,255,0,255;
+ @assert pixel 0,49 == 0,255,0,255;
+ @assert pixel 50,49 == 0,255,0,255;
+ @assert pixel 99,49 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.scale.2
+ desc: Highly scaled arcs are the right shape
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(100, 100);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 1.2;
+ ctx.beginPath();
+ ctx.arc(0, 0, 0.6, 0, Math.PI/2, false);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 50,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.arc.nonfinite
+ desc: arc() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.arc(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <2*Math.PI Infinity -Infinity NaN>, <true>);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,45 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.path.rect.basic
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.newsubpath
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.rect(200, 25, 1, 1);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.closed
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.rect(100, 50, 100, 100);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.end.1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.rect(200, 100, 400, 1000);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.end.2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.rect(150, 150, 2000, 2000);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.zero.1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(0, 50, 100, 0);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.zero.2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, -100, 0, 250);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.zero.3
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.zero.4
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.rect(100, 25, 0, 0);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.zero.5
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.rect(100, 25, 0, 0);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.rect.zero.6
+ #mozilla: { bug: TODO }
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.rect(100, 25, 1000, 0);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.rect.negative
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 50, 25);
+ ctx.rect(100, 0, -50, 25);
+ ctx.rect(0, 50, 50, -25);
+ ctx.rect(100, 50, -50, -25);
+ ctx.fill();
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+
+- name: 2d.path.rect.winding
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.rect(0, 0, 50, 50);
+ ctx.rect(100, 50, -50, -50);
+ ctx.rect(0, 25, 100, -25);
+ ctx.rect(100, 25, -100, 25);
+ ctx.fill();
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+
+- name: 2d.path.rect.selfintersect
+ #mozilla: { bug: TODO }
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.rect(45, 20, 10, 10);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.rect.nonfinite
+ desc: rect() with Infinity/NaN is ignored
+ code: |
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.rect(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.newsubpath
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.roundRect(200, 25, 1, 1, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.closed
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.roundRect(100, 50, 100, 100, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.end.1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(200, 100, 400, 1000, [0]);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.end.2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.roundRect(150, 150, 2000, 2000, [0]);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.end.3
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.roundRect(101, 51, 2000, 2000, [500, 500, 500, 500]);
+ ctx.lineTo(-1, -1);
+ ctx.stroke();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.end.4
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.roundRect(-1, -1, 2000, 2000, [1000, 1000, 1000, 1000]);
+ ctx.lineTo(-150, -150);
+ ctx.stroke();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.zero.1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(0, 50, 100, 0, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.zero.2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, -100, 0, 250, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.zero.3
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.roundRect(50, 25, 0, 0, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.zero.4
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.zero.5
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.roundRect(100, 25, 0, 0, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.zero.6
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.roundRect(100, 25, 1000, 0, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.negative
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.roundRect(0, 0, 50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 0, -50, 25, [10, 0, 0, 0]);
+ ctx.roundRect(0, 50, 50, -25, [10, 0, 0, 0]);
+ ctx.roundRect(100, 50, -50, -25, [10, 0, 0, 0]);
+ ctx.fill();
+ // All rects drawn
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+ // Correct corners are rounded.
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.winding
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 50, 50, [0]);
+ ctx.roundRect(100, 50, -50, -50, [0]);
+ ctx.roundRect(0, 25, 100, -25, [0]);
+ ctx.roundRect(100, 25, -100, 25, [0]);
+ ctx.fill();
+ @assert pixel 25,12 == 0,255,0,255;
+ @assert pixel 75,12 == 0,255,0,255;
+ @assert pixel 25,37 == 0,255,0,255;
+ @assert pixel 75,37 == 0,255,0,255;
+
+- name: 2d.path.roundrect.selfintersect
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.roundRect(0, 0, 100, 50, [0]);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.roundRect(45, 20, 10, 10, [0]);
+ ctx.stroke();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.nonfinite
+ desc: roundRect() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ @nonfinite ctx.roundRect(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <[0] [Infinity] [-Infinity] [NaN] [Infinity,0] [-Infinity,0] [NaN,0] [0,Infinity] [0,-Infinity] [0,NaN] [Infinity,0,0] [-Infinity,0,0] [NaN,0,0] [0,Infinity,0] [0,-Infinity,0] [0,NaN,0] [0,0,Infinity] [0,0,-Infinity] [0,0,NaN] [Infinity,0,0,0] [-Infinity,0,0,0] [NaN,0,0,0] [0,Infinity,0,0] [0,-Infinity,0,0] [0,NaN,0,0] [0,0,Infinity,0] [0,0,-Infinity,0] [0,0,NaN,0] [0,0,0,Infinity] [0,0,0,-Infinity] [0,0,0,NaN]>);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, -Infinity)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(10, NaN)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(-Infinity, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [new DOMPoint(NaN, 10)]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: -Infinity}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: 10, y: NaN}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: -Infinity, y: 10}]);
+ ctx.roundRect(0, 0, 100, 100, [{x: NaN, y: 10}]);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 90,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.roundrect.4.radii.1.double
+ desc: Verify that when four radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.1.dompoint
+ desc: Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.1.dompointinit
+ desc: Verify that when four radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.2.double
+ desc: Verify that when four radii are given to roundRect(), the second radius, specified as a double, applies to the top-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.2.dompoint
+ desc: Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPoint, applies to the top-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.2.dompointinit
+ desc: Verify that when four radii are given to roundRect(), the second radius, specified as a DOMPointInit, applies to the top-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.3.double
+ desc: Verify that when four radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.3.dompoint
+ desc: Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.3.dompointinit
+ desc: Verify that when four radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.4.double
+ desc: Verify that when four radii are given to roundRect(), the fourth radius, specified as a double, applies to the bottom-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.4.radii.4.dompoint
+ desc: Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPoint, applies to the bottom-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.4.radii.4.dompointinit
+ desc: Verify that when four radii are given to roundRect(), the fourth radius, specified as a DOMPointInit, applies to the bottom-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.1.double
+ desc: Verify that when three radii are given to roundRect(), the first radius, specified as a double, applies to the top-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.1.dompoint
+ desc: Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPoint, applies to the top-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.1.dompointinit
+ desc: Verify that when three radii are given to roundRect(), the first radius, specified as a DOMPointInit, applies to the top-left corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.2.double
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.3.radii.2.dompoint
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.2.dompointinit
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.3.double
+ desc: Verify that when three radii are given to roundRect(), the third radius, specified as a double, applies to the bottom-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.3.dompoint
+ desc: Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPoint, applies to the bottom-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.3.radii.3.dompointinit
+ desc: Verify that when three radii are given to roundRect(), the third radius, specified as a DOMPointInit, applies to the bottom-right corner.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.2.radii.1.double
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.2.radii.1.dompoint
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20), 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.2.radii.1.dompointinit
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}, 0]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 98,1 == 0,255,0,255;
+ @assert pixel 1,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.2.radii.2.double
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, 20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.2.radii.2.dompoint
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.2.radii.2.dompointinit
+ desc: 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.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [0, {x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+ // other corners
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+
+- name: 2d.path.roundrect.1.radius.double
+ desc: Verify that when one radius is given to roundRect(), specified as a double, it applies to all corners.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [20]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.1.radius.double.single.argument
+ desc: Verify that when one radius is given to roundRect() as a non-array argument, specified as a double, it applies to all corners.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, 20);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.1.radius.dompoint
+ desc: Verify that when one radius is given to roundRect(), specified as a DOMPoint, it applies to all corners.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [new DOMPoint(40, 20)]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+- name: 2d.path.roundrect.1.radius.dompoint.single argument
+ desc: Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPoint, it applies to all corners.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, new DOMPoint(40, 20));
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+- name: 2d.path.roundrect.1.radius.dompointinit
+ desc: Verify that when one radius is given to roundRect(), specified as a DOMPointInit, applies to all corners.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [{x: 40, y: 20}]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+- name: 2d.path.roundrect.1.radius.dompointinit.single.argument
+ desc: Verify that when one radius is given to roundRect() as a non-array argument, specified as a DOMPointInit, applies to all corners.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, {x: 40, y: 20});
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ // top-left corner
+ @assert pixel 20,1 == 255,0,0,255;
+ @assert pixel 41,1 == 0,255,0,255;
+ @assert pixel 1,10 == 255,0,0,255;
+ @assert pixel 1,21 == 0,255,0,255;
+
+ // top-right corner
+ @assert pixel 79,1 == 255,0,0,255;
+ @assert pixel 58,1 == 0,255,0,255;
+ @assert pixel 98,10 == 255,0,0,255;
+ @assert pixel 98,21 == 0,255,0,255;
+
+ // bottom-right corner
+ @assert pixel 79,48 == 255,0,0,255;
+ @assert pixel 58,48 == 0,255,0,255;
+ @assert pixel 98,39 == 255,0,0,255;
+ @assert pixel 98,28 == 0,255,0,255;
+
+ // bottom-left corner
+ @assert pixel 20,48 == 255,0,0,255;
+ @assert pixel 41,48 == 0,255,0,255;
+ @assert pixel 1,39 == 255,0,0,255;
+ @assert pixel 1,28 == 0,255,0,255;
+
+- name: 2d.path.roundrect.radius.intersecting.1
+ desc: Check that roundRects with intersecting corner arcs are rendered correctly.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [40, 40, 40, 40]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 2,25 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 50,48 == 0,255,0,255;
+ @assert pixel 97,25 == 0,255,0,255;
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.radius.intersecting.2
+ desc: Check that roundRects with intersecting corner arcs are rendered correctly.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(0, 0, 100, 50, [1000, 1000, 1000, 1000]);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 2,25 == 0,255,0,255;
+ @assert pixel 50,1 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 50,48 == 0,255,0,255;
+ @assert pixel 97,25 == 0,255,0,255;
+ @assert pixel 1,1 == 255,0,0,255;
+ @assert pixel 98,1 == 255,0,0,255;
+ @assert pixel 1,48 == 255,0,0,255;
+ @assert pixel 98,48 == 255,0,0,255;
+
+- name: 2d.path.roundrect.radius.none
+ desc: Check that roundRect throws an RangeError if radii is an empty array.
+ code: |
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])});
+
+- name: 2d.path.roundrect.radius.noargument
+ desc: Check that roundRect draws a rectangle when no radii are provided.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.roundRect(10, 10, 80, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ // upper left corner (10, 10)
+ @assert pixel 10,9 == 255,0,0,255;
+ @assert pixel 9,10 == 255,0,0,255;
+ @assert pixel 10,10 == 0,255,0,255;
+
+ // upper right corner (89, 10)
+ @assert pixel 90,10 == 255,0,0,255;
+ @assert pixel 89,9 == 255,0,0,255;
+ @assert pixel 89,10 == 0,255,0,255;
+
+ // lower right corner (89, 39)
+ @assert pixel 89,40 == 255,0,0,255;
+ @assert pixel 90,39 == 255,0,0,255;
+ @assert pixel 89,39 == 0,255,0,255;
+
+ // lower left corner (10, 30)
+ @assert pixel 9,39 == 255,0,0,255;
+ @assert pixel 10,40 == 255,0,0,255;
+ @assert pixel 10,39 == 0,255,0,255;
+
+- name: 2d.path.roundrect.radius.toomany
+ desc: Check that roundRect throws an IndeSizeError if radii has more than four items.
+ code: |
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [0, 0, 0, 0, 0])});
+
+- name: 2d.path.roundrect.radius.negative
+ desc: roundRect() with negative radius throws an exception
+ code: |
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [-1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [1, -1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(-1, 1), 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [new DOMPoint(1, -1)])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: -1, y: 1}, 1])});
+ assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 0, 0, [{x: 1, y: -1}])});
+
+- name: 2d.path.roundrect.badinput
+ desc: roundRect() throws or does not throw errors given the strange inputs.
+ code: |
+ ctx.roundRect(0, 0, 100, 100, { foo: "bar" }); //=> DOMPointInit
+ ctx.roundRect(0, 0, 100, 100, undefined); //=> "missing" -> 0
+ ctx.roundRect(0, 0, 100, 100, [[]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [[25]]); //=> « DOMPointInit »
+ ctx.roundRect(0, 0, 100, 100, [undefined]); //=> « DOMPointInit »
+ @assert throws TypeError ctx.roundRect(0, 0, 100, 100, 0n);
+ @assert throws TypeError ctx.roundRect(0, 0, 100, 100, { x: 0n });
+ @assert throws TypeError ctx.roundRect(0, 0, 100, 100, [{ x: 0n }]);
+
+- name: 2d.path.ellipse.basics
+ desc: Verify canvas throws error when drawing ellipse with negative radii.
+ code: |
+ ctx.ellipse(10, 10, 10, 5, 0, 0, 1, false);
+ ctx.ellipse(10, 10, 10, 0, 0, 0, 1, false);
+ ctx.ellipse(10, 10, -0, 5, 0, 0, 1, false);
+ @assert throws INDEX_SIZE_ERR ctx.ellipse(10, 10, -2, 5, 0, 0, 1, false);
+ @assert throws INDEX_SIZE_ERR ctx.ellipse(10, 10, 0, -1.5, 0, 0, 1, false);
+ @assert throws INDEX_SIZE_ERR ctx.ellipse(10, 10, -2, -5, 0, 0, 1, false);
+ ctx.ellipse(80, 0, 10, 4294967277, Math.PI / -84, -Math.PI / 2147483436, false);
+
+- name: 2d.path.fill.overlap
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.rect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.rect(10, 10, 80, 30);
+ ctx.fill();
+
+ @assert pixel 50,25 ==~ 0,127,0,255 +/- 1;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0, 0.5, 0)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.path.fill.winding.add
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.fill.winding.subtract.1
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.fill.winding.subtract.2
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.fill.winding.subtract.3
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(120, -20);
+ ctx.lineTo(120, 70);
+ ctx.lineTo(-20, 70);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.fill.closed.basic
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.fill.closed.unaffected
+ code: |
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ @assert pixel 90,10 == 0,255,0,255;
+ @assert pixel 10,40 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.stroke.overlap
+ desc: Stroked subpaths are combined before being drawn
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 20);
+ ctx.lineTo(100, 20);
+ ctx.moveTo(0, 30);
+ ctx.lineTo(100, 30);
+ ctx.stroke();
+
+ @assert pixel 50,25 ==~ 0,127,0,255 +/- 1;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0, 0.5, 0)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.path.stroke.union
+ desc: Strokes in opposite directions are unioned, not subtracted
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 40;
+ ctx.moveTo(0, 10);
+ ctx.lineTo(100, 10);
+ ctx.moveTo(100, 40);
+ ctx.lineTo(0, 40);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.stroke.unaffected
+ desc: Stroking does not start a new path or subpath
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+
+ ctx.closePath();
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.stroke.scale1
+ desc: Stroke line widths are scaled by the current transformation matrix
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ @assert pixel 0,0 == 0,255,0,255;
+ @assert pixel 50,0 == 0,255,0,255;
+ @assert pixel 99,0 == 0,255,0,255;
+ @assert pixel 0,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 99,25 == 0,255,0,255;
+ @assert pixel 0,49 == 0,255,0,255;
+ @assert pixel 50,49 == 0,255,0,255;
+ @assert pixel 99,49 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.stroke.scale2
+ desc: Stroke line widths are scaled by the current transformation matrix
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ @assert pixel 0,0 == 0,255,0,255;
+ @assert pixel 50,0 == 0,255,0,255;
+ @assert pixel 99,0 == 0,255,0,255;
+ @assert pixel 0,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 99,25 == 0,255,0,255;
+ @assert pixel 0,49 == 0,255,0,255;
+ @assert pixel 50,49 == 0,255,0,255;
+ @assert pixel 99,49 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.stroke.skew
+ desc: Strokes lines are skewed by the current transformation matrix
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(49, -50);
+ ctx.lineTo(201, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 283);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ @assert pixel 0,0 == 0,255,0,255;
+ @assert pixel 50,0 == 0,255,0,255;
+ @assert pixel 99,0 == 0,255,0,255;
+ @assert pixel 0,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 99,25 == 0,255,0,255;
+ @assert pixel 0,49 == 0,255,0,255;
+ @assert pixel 50,49 == 0,255,0,255;
+ @assert pixel 99,49 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.stroke.empty
+ desc: Empty subpaths are not stroked
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(40, 25);
+ ctx.moveTo(60, 25);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.stroke.prune.line
+ desc: Zero-length line segments from lineTo are removed before stroking
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.stroke.prune.closed
+ desc: Zero-length line segments from closed paths are removed before stroking
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.closePath();
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.stroke.prune.curve
+ desc: Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed
+ before stroking
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.quadraticCurveTo(50, 25, 50, 25);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.stroke.prune.arc
+ desc: Zero-length line segments from arcTo and arc are removed before stroking
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 150, 25, 10);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(60, 25);
+ ctx.arc(50, 25, 10, 0, 0, false);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.stroke.prune.rect
+ desc: Zero-length line segments from rect and strokeRect are removed before stroking
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+
+ ctx.strokeRect(50, 25, 0, 0);
+
+ @assert pixel 50,25 == 0,255,0,255; @moz-todo
+ expected: green
+
+- name: 2d.path.stroke.prune.corner
+ desc: Zero-length line segments are removed before stroking with miters
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.4;
+
+ ctx.beginPath();
+ ctx.moveTo(-1000, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 1000);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.transformation.basic
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-100, 0);
+ ctx.rect(100, 0, 100, 50);
+ ctx.translate(0, -100);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.transformation.multiple
+ # TODO: change this name
+ desc: Transformations are applied while building paths, not when drawing
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.translate(-100, 0);
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ ctx.translate(100, 0);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.translate(0, -50);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ ctx.translate(0, 50);
+ ctx.stroke();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.transformation.changing
+ desc: Transformations are applied while building paths, not when drawing
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.translate(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.translate(-100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(1000, 1000);
+ ctx.rotate(Math.PI/2);
+ ctx.scale(0.1, 0.1);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.path.clip.empty
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.clip.basic.1
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.clip.basic.2
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(-100, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.clip.intersect
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50)
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.clip.winding.1
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.clip.winding.2
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.clip();
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.path.clip.unaffected
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.lineTo(0, 0);
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+
+
+- name: 2d.path.isPointInPath.basic.1
+ desc: isPointInPath() detects whether the point is inside the path
+ code: |
+ ctx.rect(0, 0, 20, 20);
+ @assert ctx.isPointInPath(10, 10) === true;
+ @assert ctx.isPointInPath(30, 10) === false;
+
+- name: 2d.path.isPointInPath.basic.2
+ desc: isPointInPath() detects whether the point is inside the path
+ code: |
+ ctx.rect(20, 0, 20, 20);
+ @assert ctx.isPointInPath(10, 10) === false;
+ @assert ctx.isPointInPath(30, 10) === true;
+
+- name: 2d.path.isPointInPath.edge
+ desc: isPointInPath() counts points on the path as being inside
+ code: |
+ ctx.rect(0, 0, 20, 20);
+ @assert ctx.isPointInPath(0, 0) === true;
+ @assert ctx.isPointInPath(10, 0) === true;
+ @assert ctx.isPointInPath(20, 0) === true;
+ @assert ctx.isPointInPath(20, 10) === true;
+ @assert ctx.isPointInPath(20, 20) === true;
+ @assert ctx.isPointInPath(10, 20) === true;
+ @assert ctx.isPointInPath(0, 20) === true;
+ @assert ctx.isPointInPath(0, 10) === true;
+ @assert ctx.isPointInPath(10, -0.01) === false;
+ @assert ctx.isPointInPath(10, 20.01) === false;
+ @assert ctx.isPointInPath(-0.01, 10) === false;
+ @assert ctx.isPointInPath(20.01, 10) === false;
+
+- name: 2d.path.isPointInPath.empty
+ desc: isPointInPath() works when there is no path
+ code: |
+ @assert ctx.isPointInPath(0, 0) === false;
+
+- name: 2d.path.isPointInPath.subpath
+ desc: isPointInPath() uses the current path, not just the subpath
+ code: |
+ ctx.rect(0, 0, 20, 20);
+ ctx.beginPath();
+ ctx.rect(20, 0, 20, 20);
+ ctx.closePath();
+ ctx.rect(40, 0, 20, 20);
+ @assert ctx.isPointInPath(10, 10) === false;
+ @assert ctx.isPointInPath(30, 10) === true;
+ @assert ctx.isPointInPath(50, 10) === true;
+
+- name: 2d.path.isPointInPath.outside
+ desc: isPointInPath() works on paths outside the canvas
+ code: |
+ ctx.rect(0, -100, 20, 20);
+ ctx.rect(20, -10, 20, 20);
+ @assert ctx.isPointInPath(10, -110) === false;
+ @assert ctx.isPointInPath(10, -90) === true;
+ @assert ctx.isPointInPath(10, -70) === false;
+ @assert ctx.isPointInPath(30, -20) === false;
+ @assert ctx.isPointInPath(30, 0) === true;
+ @assert ctx.isPointInPath(30, 20) === false;
+
+- name: 2d.path.isPointInPath.unclosed
+ desc: isPointInPath() works on unclosed subpaths
+ code: |
+ ctx.moveTo(0, 0);
+ ctx.lineTo(20, 0);
+ ctx.lineTo(20, 20);
+ ctx.lineTo(0, 20);
+ @assert ctx.isPointInPath(10, 10) === true;
+ @assert ctx.isPointInPath(30, 10) === false;
+
+- name: 2d.path.isPointInPath.arc
+ desc: isPointInPath() works on arcs
+ code: |
+ ctx.arc(50, 25, 10, 0, Math.PI, false);
+ @assert ctx.isPointInPath(50, 10) === false;
+ @assert ctx.isPointInPath(50, 20) === false;
+ @assert ctx.isPointInPath(50, 30) === true;
+ @assert ctx.isPointInPath(50, 40) === false;
+ @assert ctx.isPointInPath(30, 20) === false;
+ @assert ctx.isPointInPath(70, 20) === false;
+ @assert ctx.isPointInPath(30, 30) === false;
+ @assert ctx.isPointInPath(70, 30) === false;
+
+- name: 2d.path.isPointInPath.bigarc
+ desc: isPointInPath() works on unclosed arcs larger than 2pi
+ opera: {bug: 320937}
+ code: |
+ ctx.arc(50, 25, 10, 0, 7, false);
+ @assert ctx.isPointInPath(50, 10) === false;
+ @assert ctx.isPointInPath(50, 20) === true;
+ @assert ctx.isPointInPath(50, 30) === true;
+ @assert ctx.isPointInPath(50, 40) === false;
+ @assert ctx.isPointInPath(30, 20) === false;
+ @assert ctx.isPointInPath(70, 20) === false;
+ @assert ctx.isPointInPath(30, 30) === false;
+ @assert ctx.isPointInPath(70, 30) === false;
+
+- name: 2d.path.isPointInPath.bezier
+ desc: isPointInPath() works on Bezier curves
+ code: |
+ ctx.moveTo(25, 25);
+ ctx.bezierCurveTo(50, -50, 50, 100, 75, 25);
+ @assert ctx.isPointInPath(25, 20) === false;
+ @assert ctx.isPointInPath(25, 30) === false;
+ @assert ctx.isPointInPath(30, 20) === true;
+ @assert ctx.isPointInPath(30, 30) === false;
+ @assert ctx.isPointInPath(40, 2) === false;
+ @assert ctx.isPointInPath(40, 20) === true;
+ @assert ctx.isPointInPath(40, 30) === false;
+ @assert ctx.isPointInPath(40, 47) === false;
+ @assert ctx.isPointInPath(45, 20) === true;
+ @assert ctx.isPointInPath(45, 30) === false;
+ @assert ctx.isPointInPath(55, 20) === false;
+ @assert ctx.isPointInPath(55, 30) === true;
+ @assert ctx.isPointInPath(60, 2) === false;
+ @assert ctx.isPointInPath(60, 20) === false;
+ @assert ctx.isPointInPath(60, 30) === true;
+ @assert ctx.isPointInPath(60, 47) === false;
+ @assert ctx.isPointInPath(70, 20) === false;
+ @assert ctx.isPointInPath(70, 30) === true;
+ @assert ctx.isPointInPath(75, 20) === false;
+ @assert ctx.isPointInPath(75, 30) === false;
+
+- name: 2d.path.isPointInPath.winding
+ desc: isPointInPath() uses the non-zero winding number rule
+ code: |
+ // Create a square ring, using opposite windings to make a hole in the centre
+ ctx.moveTo(0, 0);
+ ctx.lineTo(50, 0);
+ ctx.lineTo(50, 50);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.lineTo(10, 40);
+ ctx.lineTo(40, 40);
+ ctx.lineTo(40, 10);
+ ctx.lineTo(10, 10);
+
+ @assert ctx.isPointInPath(5, 5) === true;
+ @assert ctx.isPointInPath(25, 5) === true;
+ @assert ctx.isPointInPath(45, 5) === true;
+ @assert ctx.isPointInPath(5, 25) === true;
+ @assert ctx.isPointInPath(25, 25) === false;
+ @assert ctx.isPointInPath(45, 25) === true;
+ @assert ctx.isPointInPath(5, 45) === true;
+ @assert ctx.isPointInPath(25, 45) === true;
+ @assert ctx.isPointInPath(45, 45) === true;
+
+- name: 2d.path.isPointInPath.transform.1
+ desc: isPointInPath() handles transformations correctly
+ code: |
+ ctx.translate(50, 0);
+ ctx.rect(0, 0, 20, 20);
+ @assert ctx.isPointInPath(-40, 10) === false;
+ @assert ctx.isPointInPath(10, 10) === false;
+ @assert ctx.isPointInPath(49, 10) === false;
+ @assert ctx.isPointInPath(51, 10) === true;
+ @assert ctx.isPointInPath(69, 10) === true;
+ @assert ctx.isPointInPath(71, 10) === false;
+
+- name: 2d.path.isPointInPath.transform.2
+ desc: isPointInPath() handles transformations correctly
+ code: |
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(50, 0);
+ @assert ctx.isPointInPath(-40, 10) === false;
+ @assert ctx.isPointInPath(10, 10) === false;
+ @assert ctx.isPointInPath(49, 10) === false;
+ @assert ctx.isPointInPath(51, 10) === true;
+ @assert ctx.isPointInPath(69, 10) === true;
+ @assert ctx.isPointInPath(71, 10) === false;
+
+- name: 2d.path.isPointInPath.transform.3
+ desc: isPointInPath() handles transformations correctly
+ code: |
+ ctx.scale(-1, 1);
+ ctx.rect(-70, 0, 20, 20);
+ @assert ctx.isPointInPath(-40, 10) === false;
+ @assert ctx.isPointInPath(10, 10) === false;
+ @assert ctx.isPointInPath(49, 10) === false;
+ @assert ctx.isPointInPath(51, 10) === true;
+ @assert ctx.isPointInPath(69, 10) === true;
+ @assert ctx.isPointInPath(71, 10) === false;
+
+- name: 2d.path.isPointInPath.transform.4
+ desc: isPointInPath() handles transformations correctly
+ code: |
+ ctx.translate(50, 0);
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(0, 50);
+ @assert ctx.isPointInPath(60, 10) === false;
+ @assert ctx.isPointInPath(110, 10) === true;
+ @assert ctx.isPointInPath(110, 60) === false;
+
+- name: 2d.path.isPointInPath.nonfinite
+ desc: isPointInPath() returns false for non-finite arguments
+ code: |
+ ctx.rect(-100, -50, 200, 100);
+ @assert ctx.isPointInPath(Infinity, 0) === false;
+ @assert ctx.isPointInPath(-Infinity, 0) === false;
+ @assert ctx.isPointInPath(NaN, 0) === false;
+ @assert ctx.isPointInPath(0, Infinity) === false;
+ @assert ctx.isPointInPath(0, -Infinity) === false;
+ @assert ctx.isPointInPath(0, NaN) === false;
+ @assert ctx.isPointInPath(NaN, NaN) === false;
+
+
+- name: 2d.path.isPointInStroke.scaleddashes
+ desc: isPointInStroke() should return correct results on dashed paths at high scale
+ factors
+ code: |
+ var scale = 20;
+ ctx.setLineDash([10, 21.4159]); // dash from t=0 to t=10 along the circle
+ ctx.scale(scale, scale);
+ ctx.ellipse(6, 10, 5, 5, 0, 2*Math.PI, false);
+ ctx.stroke();
+
+ // hit-test the beginning of the dash (t=0)
+ @assert ctx.isPointInStroke(11*scale, 10*scale) === true;
+ // hit-test the middle of the dash (t=5)
+ @assert ctx.isPointInStroke(8.70*scale, 14.21*scale) === true;
+ // hit-test the end of the dash (t=9.8)
+ @assert ctx.isPointInStroke(4.10*scale, 14.63*scale) === true;
+ // hit-test past the end of the dash (t=10.2)
+ @assert ctx.isPointInStroke(3.74*scale, 14.46*scale) === false;
+
+- name: 2d.path.isPointInPath.basic
+ desc: Verify the winding rule in isPointInPath works for for rect path.
+ code: |
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ @assert ctx.isPointInPath(50, 50) === true;
+ @assert ctx.isPointInPath(NaN, 50) === false;
+ @assert ctx.isPointInPath(50, NaN) === false;
+
+ // Testing nonzero isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ @assert ctx.isPointInPath(50, 50, 'nonzero') === true;
+
+ // Testing evenodd isPointInPath
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.rect(25, 25, 50, 50);
+ @assert ctx.isPointInPath(50, 50, 'evenodd') === false;
+
+ // Testing extremely large scale
+ ctx.save();
+ ctx.scale(Number.MAX_VALUE, Number.MAX_VALUE);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ @assert ctx.isPointInPath(0, 0, 'nonzero') === true;
+ @assert ctx.isPointInPath(0, 0, 'evenodd') === true;
+ ctx.restore();
+
+ // Check with non-invertible ctm.
+ ctx.save();
+ ctx.scale(0, 0);
+ ctx.beginPath();
+ ctx.rect(-10, -10, 20, 20);
+ @assert ctx.isPointInPath(0, 0, 'nonzero') === false;
+ @assert ctx.isPointInPath(0, 0, 'evenodd') === false;
+ ctx.restore();
+
+- name: 2d.path.isPointInpath.multi.path
+ desc: Verify the winding rule in isPointInPath works for path object.
+ code: |
+ canvas.width = 200;
+ canvas.height = 200;
+
+ // Testing default isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ @assert ctx.isPointInPath(path, 50, 50) === true;
+ @assert ctx.isPointInPath(path, 50, 50, undefined) === true;
+ @assert ctx.isPointInPath(path, NaN, 50) === false;
+ @assert ctx.isPointInPath(path, 50, NaN) === false;
+
+ // Testing nonzero isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ @assert ctx.isPointInPath(path, 50, 50, 'nonzero') === true;
+
+ // Testing evenodd isPointInPath with Path object');
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ assert_false(ctx.isPointInPath(path, 50, 50, 'evenodd'));
+
+- name: 2d.path.isPointInpath.invalid
+ desc: Verify isPointInPath throws exceptions with invalid inputs.
+ code: |
+ canvas.width = 200;
+ canvas.height = 200;
+ path = new Path2D();
+ path.rect(0, 0, 100, 100);
+ path.rect(25, 25, 50, 50);
+ // Testing invalid enumeration isPointInPath (w/ and w/o Path object');
+ @assert throws TypeError ctx.isPointInPath(path, 50, 50, 'gazonk');
+ @assert throws TypeError ctx.isPointInPath(50, 50, 'gazonk');
+
+ // Testing invalid type isPointInPath with Path object');
+ @assert throws TypeError ctx.isPointInPath(null, 50, 50);
+ @assert throws TypeError ctx.isPointInPath(null, 50, 50, 'nonzero');
+ @assert throws TypeError ctx.isPointInPath(null, 50, 50, 'evenodd');
+ @assert throws TypeError ctx.isPointInPath(null, 50, 50, null);
+ @assert throws TypeError ctx.isPointInPath(path, 50, 50, null);
+ @assert throws TypeError ctx.isPointInPath(undefined, 50, 50);
+ @assert throws TypeError ctx.isPointInPath(undefined, 50, 50, 'nonzero');
+ @assert throws TypeError ctx.isPointInPath(undefined, 50, 50, 'evenodd');
+ @assert throws TypeError ctx.isPointInPath(undefined, 50, 50, undefined);
+ @assert throws TypeError ctx.isPointInPath([], 50, 50);
+ @assert throws TypeError ctx.isPointInPath([], 50, 50, 'nonzero');
+ @assert throws TypeError ctx.isPointInPath([], 50, 50, 'evenodd');
+ @assert throws TypeError ctx.isPointInPath({}, 50, 50);
+ @assert throws TypeError ctx.isPointInPath({}, 50, 50, 'nonzero');
+ @assert throws TypeError ctx.isPointInPath({}, 50, 50, 'evenodd');
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/pixel-manipulation.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/pixel-manipulation.yaml
new file mode 100644
index 0000000000..0643b047b1
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/pixel-manipulation.yaml
@@ -0,0 +1,1042 @@
+- name: 2d.imageData.create2.basic
+ desc: createImageData(sw, sh) exists and returns something
+ code: |
+ @assert ctx.createImageData(1, 1) !== null;
+
+- name: 2d.imageData.create1.basic
+ desc: createImageData(imgdata) exists and returns something
+ code: |
+ @assert ctx.createImageData(ctx.createImageData(1, 1)) !== null;
+
+- name: 2d.imageData.create2.type
+ desc: createImageData(sw, sh) returns an ImageData object containing a Uint8ClampedArray
+ object
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert window.ImageData !== undefined;
+ @assert window.Uint8ClampedArray !== undefined;
+ window.ImageData.prototype.thisImplementsImageData = true;
+ window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
+ var imgdata = ctx.createImageData(1, 1);
+ @assert imgdata.thisImplementsImageData;
+ @assert imgdata.data.thisImplementsUint8ClampedArray;
+
+- name: 2d.imageData.create1.type
+ desc: createImageData(imgdata) returns an ImageData object containing a Uint8ClampedArray
+ object
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert window.ImageData !== undefined;
+ @assert window.Uint8ClampedArray !== undefined;
+ window.ImageData.prototype.thisImplementsImageData = true;
+ window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
+ var imgdata = ctx.createImageData(ctx.createImageData(1, 1));
+ @assert imgdata.thisImplementsImageData;
+ @assert imgdata.data.thisImplementsUint8ClampedArray;
+
+- name: 2d.imageData.create2.this
+ desc: createImageData(sw, sh) should throw when called with the wrong |this|
+ canvasType: ['HTMLCanvas']
+ notes: &bindings Defined in "Web IDL" (draft)
+ code: |
+ @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(null, 1, 1); @moz-todo
+ @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(undefined, 1, 1); @moz-todo
+ @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call({}, 1, 1); @moz-todo
+
+- name: 2d.imageData.create1.this
+ desc: createImageData(imgdata) should throw when called with the wrong |this|
+ canvasType: ['HTMLCanvas']
+ notes: *bindings
+ code: |
+ var imgdata = ctx.createImageData(1, 1);
+ @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(null, imgdata); @moz-todo
+ @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(undefined, imgdata); @moz-todo
+ @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call({}, imgdata); @moz-todo
+
+- name: 2d.imageData.create2.initial
+ desc: createImageData(sw, sh) returns transparent black data of the right size
+ code: |
+ var imgdata = ctx.createImageData(10, 20);
+ @assert imgdata.data.length === imgdata.width*imgdata.height*4;
+ @assert imgdata.width < imgdata.height;
+ @assert imgdata.width > 0;
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; ++i)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ @assert isTransparentBlack;
+
+- name: 2d.imageData.create1.initial
+ desc: createImageData(imgdata) returns transparent black data of the right size
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata1 = ctx.getImageData(0, 0, 10, 20);
+ var imgdata2 = ctx.createImageData(imgdata1);
+ @assert imgdata2.data.length === imgdata1.data.length;
+ @assert imgdata2.width === imgdata1.width;
+ @assert imgdata2.height === imgdata1.height;
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata2.data.length; ++i)
+ if (imgdata2.data[i] !== 0)
+ isTransparentBlack = false;
+ @assert isTransparentBlack;
+
+- name: 2d.imageData.create2.large
+ desc: createImageData(sw, sh) works for sizes much larger than the canvas
+ code: |
+ var imgdata = ctx.createImageData(1000, 2000);
+ @assert imgdata.data.length === imgdata.width*imgdata.height*4;
+ @assert imgdata.width < imgdata.height;
+ @assert imgdata.width > 0;
+ var isTransparentBlack = true;
+ for (var i = 0; i < imgdata.data.length; i += 7813) // check ~1024 points (assuming normal scaling)
+ if (imgdata.data[i] !== 0)
+ isTransparentBlack = false;
+ @assert isTransparentBlack;
+
+- name: 2d.imageData.create2.negative
+ desc: createImageData(sw, sh) takes the absolute magnitude of the size arguments
+ code: |
+ var imgdata1 = ctx.createImageData(10, 20);
+ var imgdata2 = ctx.createImageData(-10, 20);
+ var imgdata3 = ctx.createImageData(10, -20);
+ var imgdata4 = ctx.createImageData(-10, -20);
+ @assert imgdata1.data.length === imgdata2.data.length;
+ @assert imgdata2.data.length === imgdata3.data.length;
+ @assert imgdata3.data.length === imgdata4.data.length;
+
+- name: 2d.imageData.create2.zero
+ desc: createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero
+ code: |
+ @assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0);
+ @assert throws INDEX_SIZE_ERR ctx.createImageData(0, 10);
+ @assert throws INDEX_SIZE_ERR ctx.createImageData(0, 0);
+ @assert throws INDEX_SIZE_ERR ctx.createImageData(0.99, 10);
+ @assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0.1);
+
+- name: 2d.imageData.create2.nonfinite
+ desc: createImageData() throws TypeError if arguments are not finite
+ notes: *bindings
+ code: |
+ @nonfinite @assert throws TypeError ctx.createImageData(<10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>);
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ @nonfinite @assert throws TypeError ctx.createImageData(<10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>);
+
+- name: 2d.imageData.create1.zero
+ desc: createImageData(null) throws TypeError
+ code: |
+ @assert throws TypeError ctx.createImageData(null);
+
+- name: 2d.imageData.create2.double
+ desc: createImageData(w, h) double is converted to long
+ code: |
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.createImageData(-10.01, -10.99);
+ @assert imgdata1.width === 10;
+ @assert imgdata1.height === 10;
+ @assert imgdata2.width === 10;
+ @assert imgdata2.height === 10;
+
+- name: 2d.imageData.get.double
+ desc: createImageData(w, h) double is converted to long
+ code: |
+ var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99);
+ @assert imgdata1.width === 10;
+ @assert imgdata1.height === 10;
+ @assert imgdata2.width === 10;
+ @assert imgdata2.height === 10;
+
+- name: 2d.imageData.create2.round
+ desc: createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)
+ code: |
+ var imgdata1 = ctx.createImageData(10.01, 10.99);
+ var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
+ @assert imgdata1.width === imgdata2.width;
+ @assert imgdata1.height === imgdata2.height;
+
+- name: 2d.imageData.create.and.resize
+ desc: Verify no crash when resizing an image bitmap to zero.
+ canvasType: ['HTMLCanvas']
+ images:
+ - red.png
+ code: |
+ var image = new Image();
+ image.onload = t.step_func(function() {
+ var options = { resizeHeight: 0 };
+ var p1 = createImageBitmap(image, options);
+ p1.catch(function(error){});
+ t.done();
+ });
+ image.src = 'red.png';
+
+- name: 2d.imageData.get.basic
+ desc: getImageData() exists and returns something
+ code: |
+ @assert ctx.getImageData(0, 0, 100, 50) !== null;
+
+- name: 2d.imageData.get.type
+ canvasType: ['HTMLCanvas']
+ desc: getImageData() returns an ImageData object containing a Uint8ClampedArray
+ object
+ code: |
+ @assert window.ImageData !== undefined;
+ @assert window.Uint8ClampedArray !== undefined;
+ window.ImageData.prototype.thisImplementsImageData = true;
+ window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
+ var imgdata = ctx.getImageData(0, 0, 1, 1);
+ @assert imgdata.thisImplementsImageData;
+ @assert imgdata.data.thisImplementsUint8ClampedArray;
+
+- name: 2d.imageData.get.zero
+ desc: getImageData() throws INDEX_SIZE_ERR if size is zero
+ code: |
+ @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0);
+ @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 10);
+ @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 0);
+ @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0.1, 10);
+ @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0.99);
+ @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, -0.1, 10);
+ @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, -0.99);
+
+- name: 2d.imageData.get.nonfinite
+ desc: getImageData() throws TypeError if arguments are not finite
+ notes: *bindings
+ code: |
+ @nonfinite @assert throws TypeError ctx.getImageData(<10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>);
+ var posinfobj = { valueOf: function() { return Infinity; } },
+ neginfobj = { valueOf: function() { return -Infinity; } },
+ nanobj = { valueOf: function() { return -Infinity; } };
+ @nonfinite @assert throws TypeError ctx.getImageData(<10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>);
+
+- name: 2d.imageData.get.source.outside
+ desc: getImageData() returns transparent black outside the canvas
+ code: |
+ ctx.fillStyle = '#08f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var imgdata1 = ctx.getImageData(-10, 5, 1, 1);
+ @assert imgdata1.data[0] === 0;
+ @assert imgdata1.data[1] === 0;
+ @assert imgdata1.data[2] === 0;
+ @assert imgdata1.data[3] === 0;
+
+ var imgdata2 = ctx.getImageData(10, -5, 1, 1);
+ @assert imgdata2.data[0] === 0;
+ @assert imgdata2.data[1] === 0;
+ @assert imgdata2.data[2] === 0;
+ @assert imgdata2.data[3] === 0;
+
+ var imgdata3 = ctx.getImageData(200, 5, 1, 1);
+ @assert imgdata3.data[0] === 0;
+ @assert imgdata3.data[1] === 0;
+ @assert imgdata3.data[2] === 0;
+ @assert imgdata3.data[3] === 0;
+
+ var imgdata4 = ctx.getImageData(10, 60, 1, 1);
+ @assert imgdata4.data[0] === 0;
+ @assert imgdata4.data[1] === 0;
+ @assert imgdata4.data[2] === 0;
+ @assert imgdata4.data[3] === 0;
+
+ var imgdata5 = ctx.getImageData(100, 10, 1, 1);
+ @assert imgdata5.data[0] === 0;
+ @assert imgdata5.data[1] === 0;
+ @assert imgdata5.data[2] === 0;
+ @assert imgdata5.data[3] === 0;
+
+ var imgdata6 = ctx.getImageData(0, 10, 1, 1);
+ @assert imgdata6.data[0] === 0;
+ @assert imgdata6.data[1] === 136;
+ @assert imgdata6.data[2] === 255;
+ @assert imgdata6.data[3] === 255;
+
+ var imgdata7 = ctx.getImageData(-10, 10, 20, 20);
+ @assert imgdata7.data[ 0*4+0] === 0;
+ @assert imgdata7.data[ 0*4+1] === 0;
+ @assert imgdata7.data[ 0*4+2] === 0;
+ @assert imgdata7.data[ 0*4+3] === 0;
+ @assert imgdata7.data[ 9*4+0] === 0;
+ @assert imgdata7.data[ 9*4+1] === 0;
+ @assert imgdata7.data[ 9*4+2] === 0;
+ @assert imgdata7.data[ 9*4+3] === 0;
+ @assert imgdata7.data[10*4+0] === 0;
+ @assert imgdata7.data[10*4+1] === 136;
+ @assert imgdata7.data[10*4+2] === 255;
+ @assert imgdata7.data[10*4+3] === 255;
+ @assert imgdata7.data[19*4+0] === 0;
+ @assert imgdata7.data[19*4+1] === 136;
+ @assert imgdata7.data[19*4+2] === 255;
+ @assert imgdata7.data[19*4+3] === 255;
+ @assert imgdata7.data[20*4+0] === 0;
+ @assert imgdata7.data[20*4+1] === 0;
+ @assert imgdata7.data[20*4+2] === 0;
+ @assert imgdata7.data[20*4+3] === 0;
+
+- name: 2d.imageData.get.source.negative
+ desc: getImageData() works with negative width and height, and returns top-to-bottom
+ left-to-right
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+
+ var imgdata1 = ctx.getImageData(85, 25, -10, -10);
+ @assert imgdata1.data[0] === 255;
+ @assert imgdata1.data[1] === 255;
+ @assert imgdata1.data[2] === 255;
+ @assert imgdata1.data[3] === 255;
+ @assert imgdata1.data[imgdata1.data.length-4+0] === 0;
+ @assert imgdata1.data[imgdata1.data.length-4+1] === 0;
+ @assert imgdata1.data[imgdata1.data.length-4+2] === 0;
+ @assert imgdata1.data[imgdata1.data.length-4+3] === 255;
+
+ var imgdata2 = ctx.getImageData(0, 0, -1, -1);
+ @assert imgdata2.data[0] === 0;
+ @assert imgdata2.data[1] === 0;
+ @assert imgdata2.data[2] === 0;
+ @assert imgdata2.data[3] === 0;
+
+- name: 2d.imageData.get.source.size
+ desc: getImageData() returns bigger ImageData for bigger source rectangle
+ code: |
+ var imgdata1 = ctx.getImageData(0, 0, 10, 10);
+ var imgdata2 = ctx.getImageData(0, 0, 20, 20);
+ @assert imgdata2.width > imgdata1.width;
+ @assert imgdata2.height > imgdata1.height;
+
+- name: 2d.imageData.get.nonpremul
+ desc: getImageData() returns non-premultiplied colors
+ code: |
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(10, 10, 10, 10);
+ @assert imgdata.data[0] > 200;
+ @assert imgdata.data[1] > 200;
+ @assert imgdata.data[2] > 200;
+ @assert imgdata.data[3] > 100;
+ @assert imgdata.data[3] < 200;
+
+- name: 2d.imageData.get.range
+ desc: getImageData() returns values in the range [0, 255]
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ @assert imgdata1.data[0] === 0;
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ @assert imgdata2.data[0] === 255;
+
+- name: 2d.imageData.get.clamp
+ desc: getImageData() clamps colors to the range [0, 255]
+ code: |
+ ctx.fillStyle = 'rgb(-100, -200, -300)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgb(256, 300, 400)';
+ ctx.fillRect(20, 10, 60, 10);
+ var imgdata1 = ctx.getImageData(10, 5, 1, 1);
+ @assert imgdata1.data[0] === 0;
+ @assert imgdata1.data[1] === 0;
+ @assert imgdata1.data[2] === 0;
+ var imgdata2 = ctx.getImageData(30, 15, 1, 1);
+ @assert imgdata2.data[0] === 255;
+ @assert imgdata2.data[1] === 255;
+ @assert imgdata2.data[2] === 255;
+
+- name: 2d.imageData.get.length
+ desc: getImageData() returns a correctly-sized Uint8ClampedArray
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ @assert imgdata.data.length === imgdata.width*imgdata.height*4;
+
+- name: 2d.imageData.get.order.cols
+ desc: getImageData() returns leftmost columns first
+ code: |
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 2, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ @assert imgdata.data[0] === 0;
+ @assert imgdata.data[Math.round(imgdata.width/2*4)] === 255;
+ @assert imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)] === 0;
+
+- name: 2d.imageData.get.order.rows
+ desc: getImageData() returns topmost rows first
+ code: |
+ ctx.fillStyle = '#fff';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 2);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ @assert imgdata.data[0] === 0;
+ @assert imgdata.data[Math.floor(imgdata.width/2*4)] === 0;
+ @assert imgdata.data[(imgdata.height/2)*imgdata.width*4] === 255;
+
+- name: 2d.imageData.get.order.rgb
+ desc: getImageData() returns R then G then B
+ code: |
+ ctx.fillStyle = '#48c';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ @assert imgdata.data[0] === 0x44;
+ @assert imgdata.data[1] === 0x88;
+ @assert imgdata.data[2] === 0xCC;
+ @assert imgdata.data[3] === 255;
+ @assert imgdata.data[4] === 0x44;
+ @assert imgdata.data[5] === 0x88;
+ @assert imgdata.data[6] === 0xCC;
+ @assert imgdata.data[7] === 255;
+
+- name: 2d.imageData.get.order.alpha
+ desc: getImageData() returns A in the fourth component
+ code: |
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ @assert imgdata.data[3] < 200;
+ @assert imgdata.data[3] > 100;
+
+- name: 2d.imageData.get.unaffected
+ desc: getImageData() is not affected by context state
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50)
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.rect(0, 0, 5, 5);
+ ctx.clip();
+ var imgdata = ctx.getImageData(0, 0, 50, 50);
+ ctx.restore();
+ ctx.putImageData(imgdata, 50, 0);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.get.large.crash
+ desc: Test that canvas crash when image data cannot be allocated.
+ code: |
+ @assert throws TypeError ctx.getImageData(10, 0xffffffff, 2147483647, 10);
+
+- name: 2d.imageData.get.rounding
+ desc: Test the handling of non-integer source coordinates in getImageData().
+ code: |
+ function testDimensions(sx, sy, sw, sh, width, height)
+ {
+ imageData = ctx.getImageData(sx, sy, sw, sh);
+ @assert imageData.width == width;
+ @assert imageData.height == height;
+ }
+
+ testDimensions(0, 0, 20, 10, 20, 10);
+
+ testDimensions(.1, .2, 20, 10, 20, 10);
+ testDimensions(.9, .8, 20, 10, 20, 10);
+
+ testDimensions(0, 0, 20.9, 10.9, 20, 10);
+ testDimensions(0, 0, 20.1, 10.1, 20, 10);
+
+ testDimensions(-1, -1, 20, 10, 20, 10);
+
+ testDimensions(-1.1, 0, 20, 10, 20, 10);
+ testDimensions(-1.9, 0, 20, 10, 20, 10);
+
+- name: 2d.imageData.get.invalid
+ desc: Verify getImageData() behavior in invalid cases.
+ code: |
+ imageData = ctx.getImageData(0,0,2,2);
+ var testValues = [NaN, true, false, "\"garbage\"", "-1",
+ "0", "1", "2", Infinity, -Infinity,
+ -5, -0.5, 0, 0.5, 5,
+ 5.4, 255, 256, null, undefined];
+ var testResults = [0, 1, 0, 0, 0,
+ 0, 1, 2, 255, 0,
+ 0, 0, 0, 0, 5,
+ 5, 255, 255, 0, 0];
+ for (var i = 0; i < testValues.length; i++) {
+ imageData.data[0] = testValues[i];
+ @assert imageData.data[0] == testResults[i];
+ }
+ imageData.data['foo']='garbage';
+ @assert imageData.data['foo'] == 'garbage';
+ imageData.data[-1]='garbage';
+ @assert imageData.data[-1] == undefined;
+ imageData.data[17]='garbage';
+ @assert imageData.data[17] == undefined;
+
+- name: 2d.imageData.object.properties
+ desc: ImageData objects have the right properties
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ @assert typeof(imgdata.width) === 'number';
+ @assert typeof(imgdata.height) === 'number';
+ @assert typeof(imgdata.data) === 'object';
+
+- name: 2d.imageData.object.readonly
+ desc: ImageData objects properties are read-only
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ var w = imgdata.width;
+ var h = imgdata.height;
+ var d = imgdata.data;
+ imgdata.width = 123;
+ imgdata.height = 123;
+ imgdata.data = [100,100,100,100];
+ @assert imgdata.width === w;
+ @assert imgdata.height === h;
+ @assert imgdata.data === d;
+ @assert imgdata.data[0] === 0;
+ @assert imgdata.data[1] === 0;
+ @assert imgdata.data[2] === 0;
+ @assert imgdata.data[3] === 0;
+
+- name: 2d.imageData.object.ctor.size
+ canvasType: ['HTMLCanvas']
+ desc: ImageData has a usable constructor
+ code: |
+ @assert window.ImageData !== undefined;
+
+ var imgdata = new window.ImageData(2, 3);
+ @assert imgdata.width === 2;
+ @assert imgdata.height === 3;
+ @assert imgdata.data.length === 2 * 3 * 4;
+ for (var i = 0; i < imgdata.data.length; ++i) {
+ @assert imgdata.data[i] === 0;
+ }
+
+- name: 2d.imageData.object.ctor.basics
+ canvasType: ['HTMLCanvas']
+ desc: Testing different type of ImageData constructor
+ code: |
+ function setRGBA(imageData, i, rgba)
+ {
+ var s = i * 4;
+ imageData[s] = rgba[0];
+ imageData[s + 1] = rgba[1];
+ imageData[s + 2] = rgba[2];
+ imageData[s + 3] = rgba[3];
+ }
+
+ function getRGBA(imageData, i)
+ {
+ var result = [];
+ var s = i * 4;
+ for (var j = 0; j < 4; j++) {
+ result[j] = imageData[s + j];
+ }
+ return result;
+ }
+
+ function assertArrayEquals(actual, expected)
+ {
+ @assert typeof actual === "object";
+ @assert actual !== null;
+ @assert "length" in actual === true;
+ @assert actual.length === expected.length;
+ for (var i = 0; i < actual.length; i++) {
+ @assert actual.hasOwnProperty(i) === expected.hasOwnProperty(i);
+ @assert actual[i] === expected[i];
+ }
+ }
+
+ @assert ImageData !== undefined;
+ imageData = new ImageData(100, 50);
+
+ @assert imageData !== null;
+ @assert imageData.data !== null;
+ @assert imageData.width === 100;
+ @assert imageData.height === 50;
+ assertArrayEquals(getRGBA(imageData.data, 4), [0, 0, 0, 0]);
+
+ var testColor = [0, 255, 255, 128];
+ setRGBA(imageData.data, 4, testColor);
+ assertArrayEquals(getRGBA(imageData.data, 4), testColor);
+
+ @assert throws TypeError ImageData(1, 1);
+ @assert throws TypeError new ImageData(10);
+ @assert throws INDEX_SIZE_ERR new ImageData(0, 10);
+ @assert throws INDEX_SIZE_ERR new ImageData(10, 0);
+ @assert throws INDEX_SIZE_ERR new ImageData('width', 'height');
+ @assert throws INDEX_SIZE_ERR new ImageData(1 << 31, 1 << 31);
+ @assert throws TypeError new ImageData(new Uint8ClampedArray(0));
+ @assert throws INDEX_SIZE_ERR new ImageData(new Uint8Array(100), 25);
+ @assert throws INVALID_STATE_ERR new ImageData(new Uint8ClampedArray(27), 2);
+ @assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(28), 7, 0);
+ @assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(104), 14);
+ @assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray([12, 34, 168, 65328]), 1, 151);
+ @assert throws TypeError new ImageData(self, 4, 4);
+ @assert throws TypeError new ImageData(null, 4, 4);
+ @assert throws INDEX_SIZE_ERR new ImageData(imageData.data, 0);
+ @assert throws INDEX_SIZE_ERR new ImageData(imageData.data, 13);
+ @assert throws INDEX_SIZE_ERR new ImageData(imageData.data, 1 << 31);
+ @assert throws INDEX_SIZE_ERR new ImageData(imageData.data, 'biggish');
+ @assert throws INDEX_SIZE_ERR new ImageData(imageData.data, 1 << 24, 1 << 31);
+ @assert new ImageData(new Uint8ClampedArray(28), 7).height === 1;
+
+ imageDataFromData = new ImageData(imageData.data, 100);
+ @assert imageDataFromData.width === 100;
+ @assert imageDataFromData.height === 50;
+ @assert imageDataFromData.data === imageData.data;
+ assertArrayEquals(getRGBA(imageDataFromData.data, 10), getRGBA(imageData.data, 10));
+ setRGBA(imageData.data, 10, testColor);
+ assertArrayEquals(getRGBA(imageDataFromData.data, 10), getRGBA(imageData.data, 10));
+
+ var data = new Uint8ClampedArray(400);
+ data[22] = 129;
+ imageDataFromData = new ImageData(data, 20, 5);
+ @assert imageDataFromData.width === 20;
+ @assert imageDataFromData.height === 5;
+ @assert imageDataFromData.data === data;
+ assertArrayEquals(getRGBA(imageDataFromData.data, 2), getRGBA(data, 2));
+ setRGBA(imageDataFromData.data, 2, testColor);
+ assertArrayEquals(getRGBA(imageDataFromData.data, 2), getRGBA(data, 2));
+
+ if (window.SharedArrayBuffer) {
+ @assert throws TypeError new ImageData(new Uint16Array(new SharedArrayBuffer(32)), 4, 2);
+ }
+
+- name: 2d.imageData.object.ctor.array
+ desc: ImageData has a usable constructor
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert window.ImageData !== undefined;
+
+ var array = new Uint8ClampedArray(8);
+ var imgdata = new window.ImageData(array, 1, 2);
+ @assert imgdata.width === 1;
+ @assert imgdata.height === 2;
+ @assert imgdata.data === array;
+
+- name: 2d.imageData.object.ctor.array.bounds
+ desc: ImageData has a usable constructor
+ canvasType: ['HTMLCanvas']
+ code: |
+ @assert window.ImageData !== undefined;
+
+ @assert throws INVALID_STATE_ERR new ImageData(new Uint8ClampedArray(0), 1);
+ @assert throws INVALID_STATE_ERR new ImageData(new Uint8ClampedArray(3), 1);
+ @assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(4), 0);
+ @assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(4), 1, 2);
+ @assert throws TypeError new ImageData(new Uint8Array(8), 1, 2);
+ @assert throws TypeError new ImageData(new Int8Array(8), 1, 2);
+
+- name: 2d.imageData.object.set
+ desc: ImageData.data can be modified
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ @assert imgdata.data[0] === 100;
+ imgdata.data[0] = 200;
+ @assert imgdata.data[0] === 200;
+
+- name: 2d.imageData.object.undefined
+ desc: ImageData.data converts undefined to 0
+ webidl:
+ - es-octet
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = undefined;
+ @assert imgdata.data[0] === 0;
+
+- name: 2d.imageData.object.nan
+ desc: ImageData.data converts NaN to 0
+ webidl:
+ - es-octet
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = NaN;
+ @assert imgdata.data[0] === 0;
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "cheese";
+ @assert imgdata.data[0] === 0;
+
+- name: 2d.imageData.object.string
+ desc: ImageData.data converts strings to numbers with ToNumber
+ webidl:
+ - es-octet
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "110";
+ @assert imgdata.data[0] === 110;
+ imgdata.data[0] = 100;
+ imgdata.data[0] = "0x78";
+ @assert imgdata.data[0] === 120;
+ imgdata.data[0] = 100;
+ imgdata.data[0] = " +130e0 ";
+ @assert imgdata.data[0] === 130;
+
+- name: 2d.imageData.object.clamp
+ desc: ImageData.data clamps numbers to [0, 255]
+ webidl:
+ - es-octet
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 300;
+ @assert imgdata.data[0] === 255;
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -100;
+ @assert imgdata.data[0] === 0;
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = 200+Math.pow(2, 32);
+ @assert imgdata.data[0] === 255;
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -200-Math.pow(2, 32);
+ @assert imgdata.data[0] === 0;
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Math.pow(10, 39);
+ @assert imgdata.data[0] === 255;
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Math.pow(10, 39);
+ @assert imgdata.data[0] === 0;
+
+ imgdata.data[0] = 100;
+ imgdata.data[0] = -Infinity;
+ @assert imgdata.data[0] === 0;
+ imgdata.data[0] = 100;
+ imgdata.data[0] = Infinity;
+ @assert imgdata.data[0] === 255;
+
+- name: 2d.imageData.object.round
+ desc: ImageData.data rounds numbers with round-to-zero
+ webidl:
+ - es-octet
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ imgdata.data[0] = 0.499;
+ @assert imgdata.data[0] === 0;
+ imgdata.data[0] = 0.5;
+ @assert imgdata.data[0] === 0;
+ imgdata.data[0] = 0.501;
+ @assert imgdata.data[0] === 1;
+ imgdata.data[0] = 1.499;
+ @assert imgdata.data[0] === 1;
+ imgdata.data[0] = 1.5;
+ @assert imgdata.data[0] === 2;
+ imgdata.data[0] = 1.501;
+ @assert imgdata.data[0] === 2;
+ imgdata.data[0] = 2.5;
+ @assert imgdata.data[0] === 2;
+ imgdata.data[0] = 3.5;
+ @assert imgdata.data[0] === 4;
+ imgdata.data[0] = 252.5;
+ @assert imgdata.data[0] === 252;
+ imgdata.data[0] = 253.5;
+ @assert imgdata.data[0] === 254;
+ imgdata.data[0] = 254.5;
+ @assert imgdata.data[0] === 254;
+ imgdata.data[0] = 256.5;
+ @assert imgdata.data[0] === 255;
+ imgdata.data[0] = -0.5;
+ @assert imgdata.data[0] === 0;
+ imgdata.data[0] = -1.5;
+ @assert imgdata.data[0] === 0;
+
+
+
+- name: 2d.imageData.put.null
+ desc: putImageData() with null imagedata throws TypeError
+ code: |
+ @assert throws TypeError ctx.putImageData(null, 0, 0);
+
+- name: 2d.imageData.put.nonfinite
+ desc: putImageData() throws TypeError if arguments are not finite
+ notes: *bindings
+ code: |
+ var imgdata = ctx.getImageData(0, 0, 10, 10);
+ @nonfinite @assert throws TypeError ctx.putImageData(<imgdata>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>);
+ @nonfinite @assert throws TypeError ctx.putImageData(<imgdata>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>);
+
+- name: 2d.imageData.put.basic
+ desc: putImageData() puts image data from getImageData() onto the canvas
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.created
+ desc: putImageData() puts image data from createImageData() onto the canvas
+ code: |
+ var imgdata = ctx.createImageData(100, 50);
+ for (var i = 0; i < imgdata.data.length; i += 4) {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ imgdata.data[i+2] = 0;
+ imgdata.data[i+3] = 255;
+ }
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.wrongtype
+ desc: putImageData() does not accept non-ImageData objects
+ code: |
+ var imgdata = { width: 1, height: 1, data: [255, 0, 0, 255] };
+ @assert throws TypeError ctx.putImageData(imgdata, 0, 0);
+ @assert throws TypeError ctx.putImageData("cheese", 0, 0);
+ @assert throws TypeError ctx.putImageData(42, 0, 0);
+ expected: green
+
+- name: 2d.imageData.put.cross
+ desc: putImageData() accepts image data got from a different canvas
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50)
+ var imgdata = ctx2.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.cross
+ desc: putImageData() accepts image data got from a different canvas
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50)
+ var imgdata = ctx2.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.alpha
+ desc: putImageData() puts non-solid image data correctly
+ code: |
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.25)';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,64;
+ expected: |
+ size 100 50
+ cr.set_source_rgba(0, 1, 0, 0.25)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.imageData.put.modified
+ desc: putImageData() puts modified image data correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(45, 20, 10, 10)
+ var imgdata = ctx.getImageData(45, 20, 10, 10);
+ for (var i = 0, len = imgdata.width*imgdata.height*4; i < len; i += 4)
+ {
+ imgdata.data[i] = 0;
+ imgdata.data[i+1] = 255;
+ }
+ ctx.putImageData(imgdata, 45, 20);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.dirty.zero
+ desc: putImageData() with zero-sized dirty rectangle puts nothing
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.dirty.rect1
+ desc: putImageData() only modifies areas inside the dirty rectangle, using width
+ and height
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 0, 0, 20, 20);
+
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 35,25 ==~ 0,255,0,255;
+ @assert pixel 65,25 ==~ 0,255,0,255;
+ @assert pixel 50,15 ==~ 0,255,0,255;
+ @assert pixel 50,45 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.dirty.rect2
+ desc: putImageData() only modifies areas inside the dirty rectangle, using x and
+ y
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(60, 30, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, -20, -10, 60, 30, 20, 20);
+
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 35,25 ==~ 0,255,0,255;
+ @assert pixel 65,25 ==~ 0,255,0,255;
+ @assert pixel 50,15 ==~ 0,255,0,255;
+ @assert pixel 50,45 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.dirty.negative
+ desc: putImageData() handles negative-sized dirty rectangles correctly
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 20, 20)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(40, 20, 20, 20)
+ ctx.putImageData(imgdata, 40, 20, 20, 20, -20, -20);
+
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 35,25 ==~ 0,255,0,255;
+ @assert pixel 65,25 ==~ 0,255,0,255;
+ @assert pixel 50,15 ==~ 0,255,0,255;
+ @assert pixel 50,45 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.dirty.outside
+ desc: putImageData() handles dirty rectangles outside the canvas correctly
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+
+ ctx.putImageData(imgdata, 100, 20, 20, 20, -20, -20);
+ ctx.putImageData(imgdata, 200, 200, 0, 0, 100, 50);
+ ctx.putImageData(imgdata, 40, 20, -30, -20, 30, 20);
+ ctx.putImageData(imgdata, -30, 20, 0, 0, 30, 20);
+
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 98,15 ==~ 0,255,0,255;
+ @assert pixel 98,25 ==~ 0,255,0,255;
+ @assert pixel 98,45 ==~ 0,255,0,255;
+ @assert pixel 1,5 ==~ 0,255,0,255;
+ @assert pixel 1,25 ==~ 0,255,0,255;
+ @assert pixel 1,45 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.unchanged
+ desc: putImageData(getImageData(...), ...) has no effect
+ code: |
+ var i = 0;
+ for (var y = 0; y < 16; ++y) {
+ for (var x = 0; x < 16; ++x, ++i) {
+ ctx.fillStyle = 'rgba(' + i + ',' + (Math.floor(i*1.5) % 256) + ',' + (Math.floor(i*23.3) % 256) + ',' + (i/256) + ')';
+ ctx.fillRect(x, y, 1, 1);
+ }
+ }
+ var imgdata1 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ var olddata = [];
+ for (var i = 0; i < imgdata1.data.length; ++i)
+ olddata[i] = imgdata1.data[i];
+
+ ctx.putImageData(imgdata1, 0.1, 0.2);
+
+ var imgdata2 = ctx.getImageData(0.1, 0.2, 15.8, 15.9);
+ for (var i = 0; i < imgdata2.data.length; ++i) {
+ @assert olddata[i] === imgdata2.data[i];
+ }
+
+- name: 2d.imageData.put.unaffected
+ desc: putImageData() is not affected by context state
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.globalAlpha = 0.1;
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.translate(100, 50);
+ ctx.scale(0.1, 0.1);
+ ctx.putImageData(imgdata, 0, 0);
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.clip
+ desc: putImageData() is not affected by clipping regions
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50)
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.putImageData(imgdata, 0, 0);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.imageData.put.path
+ desc: putImageData() does not affect the current path
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50)
+ ctx.rect(0, 0, 100, 50);
+ var imgdata = ctx.getImageData(0, 0, 100, 50);
+ ctx.putImageData(imgdata, 0, 0);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml
new file mode 100644
index 0000000000..086fb04e04
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/reset.yaml
@@ -0,0 +1,286 @@
+- name: 2d.reset.basic
+ desc: reset clears to transparent black
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.reset();
+ @assert pixel 0,0 == 0,0,0,0;
+ @assert pixel 50,25 == 0,0,0,0;
+ @assert pixel 25,50 == 0,0,0,0;
+ @assert pixel 100,50 == 0,0,0,0;
+ @assert pixel 0,50 == 0,0,0,0;
+ @assert pixel 100,0 == 0,0,0,0;
+ t.done();
+
+- name: 2d.reset.state
+ desc: check that the state is reset
+ code: |
+ const default_value = ctx.{{ state_name }};
+
+ ctx.{{ state_name }} = {{ new_value }};
+ @assert ctx.{{ state_name }} == {{ new_value }};
+
+ ctx.reset();
+ @assert ctx.{{ state_name }} == default_value;
+
+ variants:
+ letter_spacing:
+ state_name: letterSpacing
+ new_value: "'12px'"
+
+ word_spacing:
+ state_name: wordSpacing
+ new_value: "'12px'"
+
+ fill_style:
+ state_name: fillStyle
+ new_value: "'#ffffff'"
+
+ stroke_style:
+ state_name: strokeStyle
+ new_value: "'#ffffff'"
+
+ filter:
+ state_name: filter
+ new_value: "'blur(10px)'"
+
+ font:
+ state_name: font
+ new_value: "'25px sans-serif'"
+
+ global_alpha:
+ state_name: globalAlpha
+ new_value: 0.5
+
+ global_composite_operation:
+ state_name: globalCompositeOperation
+ new_value: "'destination-over'"
+
+ line_width:
+ state_name: lineWidth
+ new_value: 1
+
+ line_cap:
+ state_name: lineCap
+ new_value: "'square'"
+
+ line_join:
+ state_name: lineJoin
+ new_value: "'bevel'"
+
+ miter_limit:
+ state_name: miterLimit
+ new_value: 1.0
+
+ line_dash_offset:
+ state_name: lineDashOffset
+ new_value: 1.0
+
+ shadow_offset_x:
+ state_name: shadowOffsetX
+ new_value: 10.0
+
+ shadow_offset_y:
+ state_name: shadowOffsetY
+ new_value: 10.0
+
+ shadow_blur:
+ state_name: shadowBlur
+ new_value: 10.0
+
+ shadow_color:
+ state_name: shadowColor
+ new_value: "'#ff0000'"
+
+ font:
+ state_name: font
+ new_value: "'16px sans-serif'"
+
+ text_align:
+ state_name: textAlign
+ new_value: "'end'"
+
+ text_baseline:
+ state_name: textBaseline
+ new_value: "'middle'"
+
+ direction:
+ state_name: direction
+ new_value: "'rtl'"
+
+ font_kerning:
+ state_name: fontKerning
+ new_value: "'normal'"
+
+ font_stretch:
+ state_name: fontStretch
+ new_value: "'ultra-condensed'"
+
+ font_variant_caps:
+ state_name: fontVariantCaps
+ new_value: "'unicase'"
+
+ text_rendering:
+ state_name: textRendering
+ new_value: "'geometricPrecision'"
+
+ image_smoothing_enabled:
+ state_name: imageSmoothingEnabled
+ new_value: "false"
+
+ image_smoothing_quality:
+ state_name: imageSmoothingQuality
+ new_value: "'high'"
+
+- name: 2d.reset.state.transformation_matrix
+ desc: check that the state is reset
+ code: |
+ ctx.scale(2, 2);
+
+ ctx.reset();
+ @assert ctx.getTransform().isIdentity;
+
+- name: 2d.reset.state.clip
+ desc: check that the clip is reset
+ size: [200, 200]
+ code: |
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 100);
+ ctx.clip();
+
+ ctx.fillRect(0, 0, 200, 200);
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 200, 200);
+ reference: |
+ ctx.fillRect(0, 0, 200, 200);
+
+- name: 2d.reset.state.line_dash
+ desc: check that the line dash is reset
+ code: |
+ ctx.setLineDash([1, 2]);
+
+ ctx.reset();
+ @assert ctx.getLineDash().length == 0;
+
+- name: 2d.reset.render.drop_shadow
+ desc: check that drop shadows are correctly rendered after reset
+ size: [500, 500]
+ code: |
+ ctx.shadowOffsetX = 10;
+ ctx.shadowOffsetY = 10;
+ ctx.shadowColor = "red";
+ ctx.shadowBlur = 10;
+
+ ctx.reset();
+
+ ctx.fillRect(100, 100, 100, 100);
+ reference: |
+ ctx.fillRect(100, 100, 100, 100);
+
+- name: 2d.reset.render.text
+ desc: check that text is correctly rendered after reset
+ size: [400, 400]
+ code: |
+ ctx.font = "24px serif";
+ ctx.textAlign = "center";
+ ctx.textBaseline = "hanging";
+ ctx.direction = "rtl";
+ ctx.letterSpacing = "10px";
+ ctx.fontKerning = "none";
+ ctx.fontStretch = "semi-condensed";
+ ctx.fontVariantCaps = "tilting-caps";
+ ctx.textRendering = "optimizeLegibility";
+ ctx.wordSpacing = "20px";
+
+ ctx.reset();
+
+ ctx.fillText("Lorem ipsum dolor sit amet, consectetur adipiscing elit", 0, 10);
+ reference: |
+ ctx.fillText("Lorem ipsum dolor sit amet, consectetur adipiscing elit", 0, 10);
+
+- name: 2d.reset.render.line
+ desc: check that lines are correctly rendered after reset
+ size: [400, 400]
+ code: |
+ ctx.lineWidth = 10;
+ ctx.lineCap = "round";
+ ctx.lineJoin = "bevel";
+ ctx.lineDashOffset = 10;
+ ctx.setLineDash([20]);
+
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(100, 100);
+ ctx.lineTo(100, 300);
+ ctx.lineTo(300, 300);
+ ctx.lineTo(300, 100);
+ ctx.stroke();
+ reference: |
+ ctx.beginPath();
+ ctx.moveTo(100, 100);
+ ctx.lineTo(100, 300);
+ ctx.lineTo(300, 300);
+ ctx.lineTo(300, 100);
+ ctx.stroke();
+
+- name: 2d.reset.render.miter_limit
+ desc: check that the lines are correctly rendered with the default miter limit after reset
+ size: [400, 400]
+ code: |
+ ctx.miterLimit = 6;
+
+ ctx.reset();
+
+ ctx.lineWidth = 10;
+
+ ctx.beginPath();
+ ctx.moveTo(0, 100);
+ for (let i = 0; i < 24; i++) {
+ const dy = i % 2 === 0 ? 25 : -25;
+ ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
+ }
+ ctx.stroke();
+ reference: |
+ ctx.lineWidth = 10;
+
+ ctx.beginPath();
+ ctx.moveTo(0, 100);
+ for (let i = 0; i < 24; i++) {
+ const dy = i % 2 === 0 ? 25 : -25;
+ ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
+ }
+ ctx.stroke();
+
+- name: 2d.reset.render.global_composite_operation
+ desc: check that canvas correctly renders rectangles with the default global composite operation after reset
+ size: [400, 400]
+ code: |
+ ctx.globalCompositeOperation = "xor";
+
+ ctx.reset();
+
+ ctx.fillRect(10, 10, 100, 100);
+ ctx.fillRect(50, 50, 100, 100);
+ reference: |
+ ctx.fillRect(10, 10, 100, 100);
+ ctx.fillRect(50, 50, 100, 100);
+
+- name: 2d.reset.render.misc
+ desc: check that canvas correctly renders rectangles after reset (states not covered by other tests)
+ size: [400, 400]
+ code: |
+ ctx.fillStyle = "red";
+ ctx.strokeStyle = "red";
+ ctx.globalAlpha = 0.5;
+ ctx.filter = "blur(2px)";
+
+ ctx.reset();
+
+ ctx.fillRect(0, 0, 100, 100);
+ ctx.strokeRect(150, 150, 100, 100);
+ reference: |
+ ctx.fillRect(0, 0, 100, 100);
+ ctx.strokeRect(150, 150, 100, 100);
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml
new file mode 100644
index 0000000000..dd088aa396
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/scroll.yaml
@@ -0,0 +1,76 @@
+- name: 2d.scrollPathIntoView.basic
+ desc: scrollPathIntoView() works
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ @assert Math.round(rect.top) === -8;
+ @assert Math.round(rect.left) === 200;
+
+- name: 2d.scrollPathIntoView.verticalLR
+ desc: scrollPathIntoView() works in vertical-lr writing mode
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ document.documentElement.style.cssText = 'writing-mode: vertical-lr';
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ @assert Math.round(rect.top) === 100;
+ @assert Math.round(rect.left) === -4;
+
+- name: 2d.scrollPathIntoView.verticalRL
+ desc: scrollPathIntoView() works in vertical-rl writing mode
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ document.documentElement.style.cssText = 'writing-mode: vertical-rl';
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; right: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ ctx.beginPath();
+ ctx.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView();
+ var rect = canvas.getBoundingClientRect();
+ var viewportWidth = document.scrollingElement.clientWidth;
+ var canvasWidth = canvas.width;
+ @assert Math.round(rect.top) === 100;
+ @assert Math.round(rect.right) === viewportWidth + (canvasWidth - 4 - 16);
+
+- name: 2d.scrollPathIntoView.path
+ desc: scrollPathIntoView() with path argument works
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ var div = document.createElement('div');
+ div.style.cssText = 'width: 200vw; height: 200vh';
+ document.body.appendChild(div);
+ canvas.style.cssText = 'position: absolute; top: 100px; left: 200px; border: none;';
+ window.scrollTo(0, 0);
+
+ var path = new Path2D();
+ path.rect(4, 8, 16, 32);
+ ctx.scrollPathIntoView(path);
+ var rect = canvas.getBoundingClientRect();
+ @assert Math.round(rect.top) === -8;
+ @assert Math.round(rect.left) === 200;
+
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/shadows.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/shadows.yaml
new file mode 100644
index 0000000000..953ab2c555
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/shadows.yaml
@@ -0,0 +1,1090 @@
+- name: 2d.shadow.attributes.shadowBlur.initial
+ code: |
+ @assert ctx.shadowBlur === 0;
+
+- name: 2d.shadow.attributes.shadowBlur.valid
+ code: |
+ ctx.shadowBlur = 1;
+ @assert ctx.shadowBlur === 1;
+
+ ctx.shadowBlur = 0.5;
+ @assert ctx.shadowBlur === 0.5;
+
+ ctx.shadowBlur = 1e6;
+ @assert ctx.shadowBlur === 1e6;
+
+ ctx.shadowBlur = 0;
+ @assert ctx.shadowBlur === 0;
+
+- name: 2d.shadow.attributes.shadowBlur.invalid
+ code: |
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -2;
+ @assert ctx.shadowBlur === 1;
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = Infinity;
+ @assert ctx.shadowBlur === 1;
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = -Infinity;
+ @assert ctx.shadowBlur === 1;
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = NaN;
+ @assert ctx.shadowBlur === 1;
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = 'string';
+ @assert ctx.shadowBlur === 1;
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = true;
+ @assert ctx.shadowBlur === 1;
+
+ ctx.shadowBlur = 1;
+ ctx.shadowBlur = false;
+ @assert ctx.shadowBlur === 0;
+
+- name: 2d.shadow.attributes.shadowOffset.initial
+ code: |
+ @assert ctx.shadowOffsetX === 0;
+ @assert ctx.shadowOffsetY === 0;
+
+- name: 2d.shadow.attributes.shadowOffset.valid
+ code: |
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ @assert ctx.shadowOffsetX === 1;
+ @assert ctx.shadowOffsetY === 2;
+
+ ctx.shadowOffsetX = 0.5;
+ ctx.shadowOffsetY = 0.25;
+ @assert ctx.shadowOffsetX === 0.5;
+ @assert ctx.shadowOffsetY === 0.25;
+
+ ctx.shadowOffsetX = -0.5;
+ ctx.shadowOffsetY = -0.25;
+ @assert ctx.shadowOffsetX === -0.5;
+ @assert ctx.shadowOffsetY === -0.25;
+
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 0;
+ @assert ctx.shadowOffsetX === 0;
+ @assert ctx.shadowOffsetY === 0;
+
+ ctx.shadowOffsetX = 1e6;
+ ctx.shadowOffsetY = 1e6;
+ @assert ctx.shadowOffsetX === 1e6;
+ @assert ctx.shadowOffsetY === 1e6;
+
+- name: 2d.shadow.attributes.shadowOffset.invalid
+ code: |
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = Infinity;
+ ctx.shadowOffsetY = Infinity;
+ @assert ctx.shadowOffsetX === 1;
+ @assert ctx.shadowOffsetY === 2;
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = -Infinity;
+ ctx.shadowOffsetY = -Infinity;
+ @assert ctx.shadowOffsetX === 1;
+ @assert ctx.shadowOffsetY === 2;
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = NaN;
+ ctx.shadowOffsetY = NaN;
+ @assert ctx.shadowOffsetX === 1;
+ @assert ctx.shadowOffsetY === 2;
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = 'string';
+ ctx.shadowOffsetY = 'string';
+ @assert ctx.shadowOffsetX === 1;
+ @assert ctx.shadowOffsetY === 2;
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = true;
+ ctx.shadowOffsetY = true;
+ @assert ctx.shadowOffsetX === 1;
+ @assert ctx.shadowOffsetY === 1;
+
+ ctx.shadowOffsetX = 1;
+ ctx.shadowOffsetY = 2;
+ ctx.shadowOffsetX = false;
+ ctx.shadowOffsetY = false;
+ @assert ctx.shadowOffsetX === 0;
+ @assert ctx.shadowOffsetY === 0;
+
+- name: 2d.shadow.attributes.shadowColor.initial
+ code: |
+ @assert ctx.shadowColor === 'rgba(0, 0, 0, 0)';
+
+- name: 2d.shadow.attributes.shadowColor.valid
+ code: |
+ ctx.shadowColor = 'lime';
+ @assert ctx.shadowColor === '#00ff00';
+
+ ctx.shadowColor = 'RGBA(0,255, 0,0)';
+ @assert ctx.shadowColor === 'rgba(0, 255, 0, 0)';
+
+- name: 2d.shadow.attributes.shadowColor.current.basic
+ desc: currentColor is computed from the canvas element
+ canvasType: ['HtmlCanvas']
+ code: |
+ canvas.style.color = '#0f0';
+ ctx.shadowColor = 'currentColor';
+ @assert ctx.shadowColor === '#00ff00';
+
+- name: 2d.shadow.attributes.shadowColor.current.changed
+ desc: currentColor is computed when the attribute is set, not when it is painted
+ canvasType: ['HtmlCanvas']
+ code: |
+ canvas.style.color = '#0f0';
+ ctx.shadowColor = 'currentColor';
+ canvas.style.color = '#f00';
+ @assert ctx.shadowColor === '#00ff00';
+
+- name: 2d.shadow.attributes.shadowColor.current.removed
+ desc: currentColor is solid black when the canvas element is not in a document
+ canvasType: ['HtmlCanvas']
+ code: |
+ // Try not to let it undetectably incorrectly pick up opaque-black
+ // from other parts of the document:
+ document.documentElement.style.color = '#f00';
+ document.body.style.color = '#f00';
+ canvas.style.color = '#f00';
+
+ canvas.remove();
+ ctx.shadowColor = 'currentColor';
+ @assert ctx.shadowColor === '#000000';
+
+- name: 2d.shadow.attributes.shadowColor.invalid
+ code: |
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'bogus';
+ @assert ctx.shadowColor === '#00ff00';
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = 'red bogus';
+ @assert ctx.shadowColor === '#00ff00';
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = ctx;
+ @assert ctx.shadowColor === '#00ff00';
+
+ ctx.shadowColor = '#00ff00';
+ ctx.shadowColor = undefined;
+ @assert ctx.shadowColor === '#00ff00';
+
+- name: 2d.shadow.enable.off.1
+ desc: Shadows are not drawn when only shadowColor is set
+ code: |
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.enable.off.2
+ desc: Shadows are not drawn when only shadowColor is set
+ code: |
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#f00';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.enable.blur
+ desc: Shadows are drawn if shadowBlur is set
+ code: |
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowBlur = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.enable.x
+ desc: Shadows are drawn if shadowOffsetX is set
+ code: |
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.enable.y
+ desc: Shadows are drawn if shadowOffsetY is set
+ code: |
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 0.1;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.offset.positiveX
+ desc: Shadows can be offset with positive x
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.offset.negativeX
+ desc: Shadows can be offset with negative x
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = -50;
+ ctx.fillRect(50, 0, 50, 50);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.offset.positiveY
+ desc: Shadows can be offset with positive y
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 25;
+ ctx.fillRect(0, 0, 100, 25);
+ @assert pixel 50,12 == 0,255,0,255;
+ @assert pixel 50,37 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.offset.negativeY
+ desc: Shadows can be offset with negative y
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = -25;
+ ctx.fillRect(0, 25, 100, 25);
+ @assert pixel 50,12 == 0,255,0,255;
+ @assert pixel 50,37 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.outside
+ desc: Shadows of shapes outside the visible area can be offset onto the visible
+ area
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.fillRect(-100, 0, 25, 50);
+ ctx.shadowOffsetX = -100;
+ ctx.fillRect(175, 0, 25, 50);
+ ctx.shadowOffsetX = 0;
+ ctx.shadowOffsetY = 100;
+ ctx.fillRect(25, -100, 50, 25);
+ ctx.shadowOffsetY = -100;
+ ctx.fillRect(25, 125, 50, 25);
+ @assert pixel 12,25 == 0,255,0,255;
+ @assert pixel 87,25 == 0,255,0,255;
+ @assert pixel 50,12 == 0,255,0,255;
+ @assert pixel 50,37 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.clip.1
+ desc: Shadows of clipped shapes are still drawn within the clipping region
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.clip.2
+ desc: Shadows are not drawn outside the clipping region
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.restore();
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.clip.3
+ desc: Shadows of clipped shapes are still drawn within the clipping region
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 50;
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.stroke.basic
+ desc: Shadows are drawn for strokes
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, -25);
+ ctx.lineTo(100, -25);
+ ctx.stroke();
+
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.stroke.cap.1
+ desc: Shadows are not drawn for areas outside stroke caps
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'butt';
+ ctx.moveTo(-50, -25);
+ ctx.lineTo(0, -25);
+ ctx.moveTo(100, -25);
+ ctx.lineTo(150, -25);
+ ctx.stroke();
+
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.stroke.cap.2
+ desc: Shadows are drawn for stroke caps
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.beginPath();
+ ctx.lineWidth = 50;
+ ctx.lineCap = 'square';
+ ctx.moveTo(25, -25);
+ ctx.lineTo(75, -25);
+ ctx.stroke();
+
+ @assert pixel 1,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.stroke.join.1
+ desc: Shadows are not drawn for areas outside stroke joins
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.stroke.join.2
+ desc: Shadows are drawn for stroke joins
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100);
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.stroke.join.3
+ desc: Shadows are drawn for stroke joins respecting miter limit
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 0.1;
+ ctx.beginPath();
+ ctx.moveTo(-200, -50);
+ ctx.lineTo(-150, -50);
+ ctx.lineTo(-151, -100); // (not an exact right angle, to avoid some other bug in Firefox 3)
+ ctx.stroke();
+
+ @assert pixel 1,1 == 0,255,0,255;
+ @assert pixel 48,48 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,48 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.image.basic
+ desc: Shadows are drawn for images
+ images:
+ - red.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ {{ load_image }}
+ ctx.drawImage(img, 0, -50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+ variants: &load-image-variant-definition
+ _HtmlCanvas:
+ canvasType: ['HtmlCanvas']
+ load_image: var img = document.getElementById('{{ images[0] }}');
+ _OffscreenCanvas:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ test_type: promise
+ load_image: |-
+ var response = await fetch('/images/{{ images[0] }}')
+ var blob = await response.blob();
+ var img = await createImageBitmap(blob);
+
+- name: 2d.shadow.image.transparent.1
+ desc: Shadows are not drawn for transparent images
+ images:
+ - transparent.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ {{ load_image }}
+ ctx.drawImage(img, 0, -50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.image.transparent.2
+ desc: Shadows are not drawn for transparent parts of images
+ images:
+ - redtransparent.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ {{ load_image }}
+ ctx.drawImage(img, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(img, -50, -50);
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.image.alpha
+ desc: Shadows are drawn correctly for partially-transparent images
+ images:
+ - transparent50.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ {{ load_image }}
+ ctx.drawImage(img, 0, -50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.image.section
+ desc: Shadows are not drawn for areas outside image source rectangles
+ images:
+ - redtransparent.png
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#f00';
+ {{ load_image }}
+ ctx.drawImage(img, 50, 0, 50, 50, 0, -50, 50, 50);
+
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.image.scale
+ desc: Shadows are drawn correctly for scaled images
+ images:
+ - redtransparent.png
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ {{ load_image }}
+ ctx.drawImage(img, 0, 0, 100, 50, -10, -50, 240, 50);
+
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.canvas.basic
+ desc: Shadows are drawn for canvases
+ code: |
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+ variants: &create-canvas2-variant-definition
+ _HtmlCanvas:
+ canvasType: ['HtmlCanvas']
+ create_canvas2: |-
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = 100;
+ canvas2.height = 50;
+ _OffscreenCanvas:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ create_canvas2: |-
+ var canvas2 = new OffscreenCanvas(100, 50);
+
+- name: 2d.shadow.canvas.transparent.1
+ desc: Shadows are not drawn for transparent canvases
+ code: |
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.drawImage(canvas2, 0, -50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.shadow.canvas.transparent.2
+ desc: Shadows are not drawn for transparent parts of canvases
+ code: |
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#f00';
+ ctx2.fillRect(0, 0, 50, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.drawImage(canvas2, 50, -50);
+ ctx.shadowColor = '#f00';
+ ctx.drawImage(canvas2, -50, -50);
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.shadow.canvas.alpha
+ desc: Shadows are drawn correctly for partially-transparent canvases
+ code: |
+ {{ create_canvas2 }}
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = 'rgba(255, 0, 0, 0.5)';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.drawImage(canvas2, 0, -50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ variants: *create-canvas2-variant-definition
+
+- name: 2d.shadow.pattern.basic
+ desc: Shadows are drawn for fill patterns
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ images:
+ - red.png
+ code: |
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.pattern.transparent.1
+ desc: Shadows are not drawn for transparent fill patterns
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ images:
+ - transparent.png
+ code: |
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.pattern.transparent.2
+ desc: Shadows are not drawn for transparent parts of fill patterns
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ images:
+ - redtransparent.png
+ code: |
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.pattern.alpha
+ desc: Shadows are drawn correctly for partially-transparent fill patterns
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ images:
+ - transparent50.png
+ code: |
+ {{ load_image }}
+ var pattern = ctx.createPattern(img, 'repeat');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = pattern;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ variants: *load-image-variant-definition
+
+- name: 2d.shadow.gradient.basic
+ desc: Shadows are drawn for gradient fills
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ code: |
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(1, '#f00');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#0f0';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.gradient.transparent.1
+ desc: Shadows are not drawn for transparent gradient fills
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ code: |
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetY = 50;
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.gradient.transparent.2
+ desc: Shadows are not drawn for transparent parts of gradient fills
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ code: |
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, '#f00');
+ gradient.addColorStop(0.499, '#f00');
+ gradient.addColorStop(0.5, 'rgba(0,0,0,0)');
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.gradient.alpha
+ desc: Shadows are drawn correctly for partially-transparent gradient fills
+ # http://bugs.webkit.org/show_bug.cgi?id=15266
+ code: |
+ var gradient = ctx.createLinearGradient(0, 0, 100, 0);
+ gradient.addColorStop(0, 'rgba(255,0,0,0.5)');
+ gradient.addColorStop(1, 'rgba(255,0,0,0.5)');
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#00f';
+ ctx.fillStyle = gradient;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.shadow.transform.1
+ desc: Shadows take account of transformations
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.translate(100, 100);
+ ctx.fillRect(-100, -150, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.transform.2
+ desc: Shadow offsets are not affected by transformations
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowOffsetY = 50;
+ ctx.shadowColor = '#0f0';
+ ctx.rotate(Math.PI)
+ ctx.fillRect(-100, 0, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.blur.low
+ desc: Shadows look correct for small blurs
+ manual:
+ code: |
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 25;
+ for (var x = 0; x < 100; ++x) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(x, 0, 1, 50);
+ ctx.clip();
+ ctx.shadowBlur = x;
+ ctx.fillRect(-200, -200, 500, 200);
+ ctx.restore();
+ }
+ expected: |
+ size 100 50
+ import math
+ cr.set_source_rgb(0, 0, 1)
+ cr.rectangle(0, 0, 1, 25)
+ cr.fill()
+ cr.set_source_rgb(1, 1, 0)
+ cr.rectangle(0, 25, 1, 25)
+ cr.fill()
+ for x in range(1, 100):
+ sigma = x/2.0
+ filter = []
+ for i in range(-24, 26):
+ filter.append(math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma))
+ accum = [0]
+ for f in filter:
+ accum.append(accum[-1] + f)
+ for y in range(0, 50):
+ cr.set_source_rgb(accum[y], accum[y], 1-accum[y])
+ cr.rectangle(x, y, 1, 1)
+ cr.fill()
+
+- name: 2d.shadow.blur.high
+ desc: Shadows look correct for large blurs
+ manual:
+ code: |
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 0;
+ ctx.shadowBlur = 100;
+ ctx.fillRect(-200, -200, 200, 400);
+ expected: |
+ size 100 50
+ import math
+ sigma = 100.0/2
+ filter = []
+ for i in range(-200, 100):
+ filter.append(math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma))
+ accum = [0]
+ for f in filter:
+ accum.append(accum[-1] + f)
+ for x in range(0, 100):
+ cr.set_source_rgb(accum[x+200], accum[x+200], 1-accum[x+200])
+ cr.rectangle(x, 0, 1, 50)
+ cr.fill()
+
+- name: 2d.shadow.alpha.1
+ desc: Shadow color alpha components are used
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(255, 0, 0, 0.01)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 ==~ 0,255,0,255 +/- 4;
+ expected: green
+
+- name: 2d.shadow.alpha.2
+ desc: Shadow color alpha components are used
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.5)';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.shadow.alpha.3
+ desc: Shadows are affected by globalAlpha
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.5;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.shadow.alpha.4
+ desc: Shadows with alpha components are correctly affected by globalAlpha
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching)
+ ctx.shadowColor = 'rgba(0, 0, 255, 0.707)';
+ ctx.shadowOffsetY = 50;
+ ctx.globalAlpha = 0.707;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.shadow.alpha.5
+ desc: Shadows of shapes with alpha components are drawn correctly
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = 'rgba(64, 0, 0, 0.5)';
+ ctx.shadowColor = '#00f';
+ ctx.shadowOffsetY = 50;
+ ctx.fillRect(0, -50, 100, 50);
+
+ @assert pixel 50,25 ==~ 127,0,127,255;
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0.5, 0, 0.5)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+
+- name: 2d.shadow.composite.1
+ desc: Shadows are drawn using globalCompositeOperation
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowOffsetX = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, 0, 200, 50);
+
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.composite.2
+ desc: Shadows are drawn using globalCompositeOperation
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 1;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-10, -10, 120, 70);
+
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
+
+- name: 2d.shadow.composite.3
+ desc: Areas outside shadows are drawn correctly with destination-out
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.shadowColor = '#f00';
+ ctx.shadowBlur = 10;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(200, 0, 100, 50);
+
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 50,25 ==~ 0,255,0,255;
+ expected: green
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/text.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/text.yaml
new file mode 100644
index 0000000000..ca945c2953
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/text.yaml
@@ -0,0 +1,1680 @@
+- name: 2d.text.font.parse.basic
+ code: |
+ ctx.font = '20px serif';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20PX SERIF';
+ @assert ctx.font === '20px serif'; @moz-todo
+
+- name: 2d.text.font.parse.tiny
+ code: |
+ ctx.font = '1px sans-serif';
+ @assert ctx.font === '1px sans-serif';
+
+- name: 2d.text.font.parse.complex
+ code: |
+ ctx.font = 'small-caps italic 400 12px/2 Unknown Font, sans-serif';
+ @assert ['italic small-caps 12px "Unknown Font", sans-serif', 'italic small-caps 12px Unknown Font, sans-serif'].includes(ctx.font);
+
+- name: 2d.text.font.parse.complex2
+ code: |
+ ctx.font = 'small-caps italic 400 12px/2 "Unknown Font #2", sans-serif';
+ @assert ctx.font === 'italic small-caps 12px "Unknown Font #2", sans-serif';
+
+- name: 2d.text.font.parse.family
+ code: |
+ ctx.font = '20px cursive,fantasy,monospace,sans-serif,serif,UnquotedFont,"QuotedFont\\\\\\","';
+ @assert ctx.font === '20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, "QuotedFont\\\\\\","';
+
+ # TODO:
+ # 2d.text.font.parse.size.absolute
+ # xx-small x-small small medium large x-large xx-large
+ # 2d.text.font.parse.size.relative
+ # smaller larger
+ # 2d.text.font.parse.size.length.relative
+ # em ex px
+ # 2d.text.font.parse.size.length.absolute
+ # in cm mm pt pc
+
+- name: 2d.text.font.parse.size.percentage
+ canvas: 'style="font-size: 144px"'
+ canvasType: ['HtmlCanvas']
+ code: |
+ ctx.font = '50% serif';
+ @assert ctx.font === '72px serif'; @moz-todo
+ canvas.setAttribute('style', 'font-size: 100px');
+ @assert ctx.font === '72px serif'; @moz-todo
+
+- name: 2d.text.font.parse.size.percentage.default
+ canvasType: ['HtmlCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.font = '1000% serif';
+ @assert ctx2.font === '100px serif'; @moz-todo
+
+- name: 2d.text.font.parse.system
+ desc: System fonts must be computed to explicit values
+ code: |
+ ctx.font = 'message-box';
+ @assert ctx.font !== 'message-box';
+
+- name: 2d.text.font.parse.invalid
+ code: |
+ ctx.font = '20px serif';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = '';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = 'bogus';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = 'inherit';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = '10px {bogus}';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = '10px initial';
+ @assert ctx.font === '20px serif'; @moz-todo
+
+ ctx.font = '20px serif';
+ ctx.font = '10px default';
+ @assert ctx.font === '20px serif'; @moz-todo
+
+ ctx.font = '20px serif';
+ ctx.font = '10px inherit';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = '10px revert';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x)';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = 'var(--x, 10px serif)';
+ @assert ctx.font === '20px serif';
+
+ ctx.font = '20px serif';
+ ctx.font = '1em serif; background: green; margin: 10px';
+ @assert ctx.font === '20px serif';
+
+- name: 2d.text.font.default
+ code: |
+ @assert ctx.font === '10px sans-serif';
+
+- name: 2d.text.font.relative_size
+ canvasType: ['HTMLCanvas']
+ code: |
+ var canvas2 = document.createElement('canvas');
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.font = '1em sans-serif';
+ @assert ctx2.font === '10px sans-serif';
+
+- name: 2d.text.font.relative_size
+ canvasType: ['OffscreenCanvas', 'Worker']
+ code: |
+ ctx.font = '1em sans-serif';
+ @assert ctx.font === '10px sans-serif';
+
+- name: 2d.text.font.weight
+ code: |
+ ctx.font = 'italic 400 12px serif';
+ @assert ctx.font === 'italic 12px serif';
+
+ ctx.font = 'italic 300 12px serif';
+ @assert ctx.font === 'italic 300 12px serif';
+
+- name: 2d.text.align.valid
+ code: |
+ ctx.textAlign = 'start';
+ @assert ctx.textAlign === 'start';
+
+ ctx.textAlign = 'end';
+ @assert ctx.textAlign === 'end';
+
+ ctx.textAlign = 'left';
+ @assert ctx.textAlign === 'left';
+
+ ctx.textAlign = 'right';
+ @assert ctx.textAlign === 'right';
+
+ ctx.textAlign = 'center';
+ @assert ctx.textAlign === 'center';
+
+- name: 2d.text.align.invalid
+ code: |
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'bogus';
+ @assert ctx.textAlign === 'start';
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'END';
+ @assert ctx.textAlign === 'start';
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end ';
+ @assert ctx.textAlign === 'start';
+
+ ctx.textAlign = 'start';
+ ctx.textAlign = 'end\0';
+ @assert ctx.textAlign === 'start';
+
+- name: 2d.text.align.default
+ code: |
+ @assert ctx.textAlign === 'start';
+
+- name: 2d.text.baseline.valid
+ code: |
+ ctx.textBaseline = 'top';
+ @assert ctx.textBaseline === 'top';
+
+ ctx.textBaseline = 'hanging';
+ @assert ctx.textBaseline === 'hanging';
+
+ ctx.textBaseline = 'middle';
+ @assert ctx.textBaseline === 'middle';
+
+ ctx.textBaseline = 'alphabetic';
+ @assert ctx.textBaseline === 'alphabetic';
+
+ ctx.textBaseline = 'ideographic';
+ @assert ctx.textBaseline === 'ideographic';
+
+ ctx.textBaseline = 'bottom';
+ @assert ctx.textBaseline === 'bottom';
+
+- name: 2d.text.baseline.invalid
+ code: |
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'bogus';
+ @assert ctx.textBaseline === 'top';
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'MIDDLE';
+ @assert ctx.textBaseline === 'top';
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle ';
+ @assert ctx.textBaseline === 'top';
+
+ ctx.textBaseline = 'top';
+ ctx.textBaseline = 'middle\0';
+ @assert ctx.textBaseline === 'top';
+
+- name: 2d.text.baseline.default
+ code: |
+ @assert ctx.textBaseline === 'alphabetic';
+
+- name: 2d.text.draw.baseline.top
+ desc: textBaseline top is the top of the em square (not the bounding box)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'top';
+ ctx.fillText('CC', 0, 0);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: &load-font-variant-definition
+ _HtmlCanvas:
+ canvasType: ['HtmlCanvas']
+ load_font: |-
+ await document.fonts.ready;
+ _OffscreenCanvas:
+ canvasType: ['OffscreenCanvas', 'Worker']
+ load_font: |-
+ var f = new FontFace("{{ fonts[0] }}", "url('/fonts/{{ fonts[0] }}.ttf')");
+ f.load();
+ {% set root = 'self' if canvas_type == 'worker' else 'document' %}
+ {{ root }}.fonts.add(f);
+ await {{ root }}.fonts.ready;
+
+- name: 2d.text.draw.baseline.bottom
+ desc: textBaseline bottom is the bottom of the em square (not the bounding box)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'bottom';
+ ctx.fillText('CC', 0, 50);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.baseline.middle
+ desc: textBaseline middle is the middle of the em square (not the bounding box)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'middle';
+ ctx.fillText('CC', 0, 25);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.baseline.alphabetic
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'alphabetic';
+ ctx.fillText('CC', 0, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.baseline.ideographic
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'ideographic';
+ ctx.fillText('CC', 0, 31.25);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255; @moz-todo
+ @assert pixel 95,45 ==~ 0,255,0,255; @moz-todo
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.baseline.hanging
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textBaseline = 'hanging';
+ ctx.fillText('CC', 0, 12.5);
+ @assert pixel 5,5 ==~ 0,255,0,255; @moz-todo
+ @assert pixel 95,5 ==~ 0,255,0,255; @moz-todo
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.space.collapse.space
+ desc: Space characters are converted to U+0020, and are NOT collapsed
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', 0, 37.5);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 255,0,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.space.collapse.other
+ desc: Space characters are converted to U+0020, and are NOT collapsed
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dEE', 0, 37.5);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 255,0,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.space.collapse.start
+ desc: Space characters at the start of a line are NOT collapsed
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText(' EE', 0, 37.5);
+ @assert pixel 25,25 ==~ 255,0,0,255; @moz-todo
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.space.collapse.end
+ desc: Space characters at the end of a line are NOT collapsed
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('EE ', 100, 37.5);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 255,0,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.width.space
+ desc: Space characters are converted to U+0020 and NOT collapsed
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ @assert ctx.measureText('A B').width === 150;
+ @assert ctx.measureText('A B').width === 200;
+ @assert ctx.measureText('A \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dB').width === 650;
+ @assert ctx.measureText('A \x0b B').width >= 200;
+
+ @assert ctx.measureText(' AB').width === 150;
+ @assert ctx.measureText('AB ').width === 150;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.drawing.style.measure.rtl.text
+ desc: Measurement should follow canvas direction instead text direction
+ code: |
+ metrics = ctx.measureText('اَلْعَرَبِيَّةُ');
+ @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
+
+ metrics = ctx.measureText('hello');
+ @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
+
+- name: 2d.text.drawing.style.measure.textAlign
+ desc: Measurement should be related to textAlignment
+ code: |
+ ctx.textAlign = "right";
+ metrics = ctx.measureText('hello');
+ @assert metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight;
+
+ ctx.textAlign = "left"
+ metrics = ctx.measureText('hello');
+ @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
+
+- name: 2d.text.drawing.style.measure.direction
+ desc: Measurement should follow text direction
+ code: |
+ ctx.direction = "ltr";
+ metrics = ctx.measureText('hello');
+ @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
+
+ ctx.direction = "rtl";
+ metrics = ctx.measureText('hello');
+ @assert metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight;
+
+- name: 2d.text.draw.fill.basic
+ desc: fillText draws filled text
+ manual:
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35);
+ expected: &passfill |
+ size 100 50
+ cr.set_source_rgb(0, 0, 0)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ cr.set_source_rgb(0, 1, 0)
+ cr.select_font_face("Arial")
+ cr.set_font_size(35)
+ cr.translate(5, 35)
+ cr.text_path("PASS")
+ cr.fill()
+
+- name: 2d.text.draw.fill.unaffected
+ desc: fillText does not start a new path or subpath
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 5,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.text.draw.fill.rtl
+ desc: fillText respects Right-To-Left Override characters
+ manual:
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('\u202eFAIL \xa0 \xa0 SSAP', 5, 35);
+ expected: *passfill
+
+- name: 2d.text.draw.fill.maxWidth.large
+ desc: fillText handles maxWidth correctly
+ manual:
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('PASS', 5, 35, 200);
+ expected: *passfill
+
+- name: 2d.text.draw.fill.maxWidth.small
+ desc: fillText handles maxWidth correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', -100, 35, 90);
+ _assertGreen(ctx, 100, 50);
+ expected: green
+
+- name: 2d.text.draw.fill.maxWidth.zero
+ desc: fillText handles maxWidth correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, 0);
+ _assertGreen(ctx, 100, 50);
+ expected: green
+
+- name: 2d.text.draw.fill.maxWidth.negative
+ desc: fillText handles maxWidth correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, -1);
+ _assertGreen(ctx, 100, 50);
+ expected: green
+
+- name: 2d.text.draw.fill.maxWidth.NaN
+ desc: fillText handles maxWidth correctly
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.font = '35px Arial, sans-serif';
+ ctx.fillText('fail fail fail fail fail', 5, 35, NaN);
+ _assertGreen(ctx, 100, 50);
+ expected: green
+
+- name: 2d.text.draw.stroke.basic
+ desc: strokeText draws stroked text
+ manual:
+ code: |
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.fillStyle = '#f00';
+ ctx.lineWidth = 1;
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeText('PASS', 5, 35);
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0, 0, 0)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ cr.set_source_rgb(0, 1, 0)
+ cr.select_font_face("Arial")
+ cr.set_font_size(35)
+ cr.set_line_width(1)
+ cr.translate(5, 35)
+ cr.text_path("PASS")
+ cr.stroke()
+
+- name: 2d.text.draw.stroke.unaffected
+ desc: strokeText does not start a new path or subpath
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+
+ ctx.font = '35px Arial, sans-serif';
+ ctx.strokeStyle = '#f00';
+ ctx.strokeText('FAIL', 5, 35);
+
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 5,45 == 0,255,0,255;
+ expected: green
+
+- name: 2d.text.draw.kern.consistent
+ desc: Stroked and filled text should have exactly the same kerning so it overlaps
+ manual:
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 3;
+ ctx.font = '20px Arial, sans-serif';
+ ctx.fillText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.fillText('ToToToToToToTo', -50, 45);
+ ctx.strokeText('VAVAVAVAVAVAVA', -50, 25);
+ ctx.strokeText('ToToToToToToTo', -50, 45);
+ expected: green
+
+# CanvasTest is:
+# A = (0, 0) to (1em, 0.75em) (above baseline)
+# B = (0, 0) to (1em, -0.25em) (below baseline)
+# C = (0, -0.25em) to (1em, 0.75em) (the em square) plus some Xs above and below
+# D = (0, -0.25em) to (1em, 0.75em) (the em square) plus some Xs left and right
+# E = (0, -0.25em) to (1em, 0.75em) (the em square)
+# space = empty, 1em wide
+#
+# At 50px, "E" will fill the canvas vertically
+# At 67px, "A" will fill the canvas vertically
+#
+# Ideographic baseline is 0.125em above alphabetic
+# Mathematical baseline is 0.375em above alphabetic
+# Hanging baseline is 0.500em above alphabetic
+
+- name: 2d.text.draw.fill.maxWidth.fontface
+ desc: fillText works on @font-face fonts
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillText('EEEE', -50, 37.5, 40);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.fill.maxWidth.bound
+ desc: fillText handles maxWidth based on line size, not bounding box size
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('DD', 0, 37.5, 100);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.fontface
+ fonts:
+ - CanvasTest
+ test_type: promise
+ code: |
+ {{ load_font }}
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.fontface.repeat
+ desc: Draw with the font immediately, then wait a bit until and draw again. (This
+ crashes some version of WebKit.)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ font_unused_in_dom: true
+ code: |
+ {{ load_font }}
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+
+ await new Promise(resolve => t.step_timeout(resolve, 500));
+ ctx.fillText('AA', 0, 50);
+ _assertPixelApprox(canvas, 5,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 95,5, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 25,25, 0,255,0,255, 2);
+ _assertPixelApprox(canvas, 75,25, 0,255,0,255, 2);
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.fontface.notinpage
+ desc: '@font-face fonts should work even if they are not used in the page'
+ test_type: promise
+ fonts:
+ - CanvasTest
+ font_unused_in_dom: true
+ code: |
+ {{ load_font }}
+ ctx.font = '67px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('AA', 0, 50);
+ @assert pixel 5,5 ==~ 0,255,0,255; @moz-todo
+ @assert pixel 95,5 ==~ 0,255,0,255; @moz-todo
+ @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo
+ @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.align.left
+ desc: textAlign left is the left of the first em square (not the bounding box)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'left';
+ ctx.fillText('DD', 0, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.align.right
+ desc: textAlign right is the right of the last em square (not the bounding box)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'right';
+ ctx.fillText('DD', 100, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.align.start.ltr
+ desc: textAlign start with ltr is the left edge
+ canvas: dir="ltr"
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ {% if canvas_type != 'htmlcanvas' %}
+ ctx.direction = 'ltr';
+ {% endif %}
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 0, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.align.start.rtl
+ desc: textAlign start with rtl is the right edge
+ canvas: dir="rtl"
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ {% if canvas_type != 'htmlcanvas' %}
+ ctx.direction = 'rtl';
+ {% endif %}
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'start';
+ ctx.fillText('DD', 100, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.align.end.ltr
+ desc: textAlign end with ltr is the right edge
+ test_type: promise
+ canvas: dir="ltr"
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ {% if canvas_type != 'htmlcanvas' %}
+ ctx.direction = 'ltr';
+ {% endif %}
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 100, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.align.end.rtl
+ desc: textAlign end with rtl is the left edge
+ canvas: dir="rtl"
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ {% if canvas_type != 'htmlcanvas' %}
+ ctx.direction = 'rtl';
+ {% endif %}
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'end';
+ ctx.fillText('DD', 0, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.align.center
+ desc: textAlign center is the center of the em squares (not the bounding box)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.textAlign = 'center';
+ ctx.fillText('DD', 50, 37.5);
+ @assert pixel 5,5 ==~ 0,255,0,255;
+ @assert pixel 95,5 ==~ 0,255,0,255;
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ @assert pixel 5,45 ==~ 0,255,0,255;
+ @assert pixel 95,45 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+
+- name: 2d.text.draw.space.basic
+ desc: U+0020 is rendered the correct size (1em wide)
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E EE', -100, 37.5);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.draw.space.collapse.nonspace
+ desc: Non-space characters are not converted to U+0020 and collapsed
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillText('E\x0b EE', -150, 37.5);
+ @assert pixel 25,25 ==~ 0,255,0,255;
+ @assert pixel 75,25 ==~ 0,255,0,255;
+ expected: green
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.width.basic
+ desc: The width of character is same as font used
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ @assert ctx.measureText('A').width === 50;
+ @assert ctx.measureText('AA').width === 100;
+ @assert ctx.measureText('ABCD').width === 200;
+
+ ctx.font = '100px CanvasTest';
+ @assert ctx.measureText('A').width === 100;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.width.empty
+ desc: The empty string has zero width
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ @assert ctx.measureText("").width === 0;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.advances
+ desc: Testing width advances
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ // Some platforms may return '-0'.
+ @assert Math.abs(ctx.measureText('Hello').advances[0]) === 0;
+ // Different platforms may render text slightly different.
+ @assert ctx.measureText('Hello').advances[1] >= 36;
+ @assert ctx.measureText('Hello').advances[2] >= 58;
+ @assert ctx.measureText('Hello').advances[3] >= 70;
+ @assert ctx.measureText('Hello').advances[4] >= 80;
+
+ var tm = ctx.measureText('Hello');
+ @assert ctx.measureText('Hello').advances[0] === tm.advances[0];
+ @assert ctx.measureText('Hello').advances[1] === tm.advances[1];
+ @assert ctx.measureText('Hello').advances[2] === tm.advances[2];
+ @assert ctx.measureText('Hello').advances[3] === tm.advances[3];
+ @assert ctx.measureText('Hello').advances[4] === tm.advances[4];
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.actualBoundingBox
+ desc: Testing actualBoundingBox
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ ctx.baseline = 'alphabetic'
+ // Different platforms may render text slightly different.
+ // Values that are nominally expected to be zero might actually vary by a
+ // pixel or so if the UA accounts for antialiasing at glyph edges, so we
+ // allow a slight deviation.
+ @assert Math.abs(ctx.measureText('A').actualBoundingBoxLeft) <= 1;
+ @assert ctx.measureText('A').actualBoundingBoxRight >= 50;
+ @assert ctx.measureText('A').actualBoundingBoxAscent >= 35;
+ @assert Math.abs(ctx.measureText('A').actualBoundingBoxDescent) <= 1;
+
+ @assert ctx.measureText('D').actualBoundingBoxLeft >= 48;
+ @assert ctx.measureText('D').actualBoundingBoxLeft <= 52;
+ @assert ctx.measureText('D').actualBoundingBoxRight >= 75;
+ @assert ctx.measureText('D').actualBoundingBoxRight <= 80;
+ @assert ctx.measureText('D').actualBoundingBoxAscent >= 35;
+ @assert ctx.measureText('D').actualBoundingBoxAscent <= 40;
+ @assert ctx.measureText('D').actualBoundingBoxDescent >= 12;
+ @assert ctx.measureText('D').actualBoundingBoxDescent <= 15;
+
+ @assert Math.abs(ctx.measureText('ABCD').actualBoundingBoxLeft) <= 1;
+ @assert ctx.measureText('ABCD').actualBoundingBoxRight >= 200;
+ @assert ctx.measureText('ABCD').actualBoundingBoxAscent >= 85;
+ @assert ctx.measureText('ABCD').actualBoundingBoxDescent >= 37;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.fontBoundingBox
+ desc: Testing fontBoundingBox measurements
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert ctx.measureText('A').fontBoundingBoxAscent === 30;
+ @assert ctx.measureText('A').fontBoundingBoxDescent === 10;
+
+ @assert ctx.measureText('ABCD').fontBoundingBoxAscent === 30;
+ @assert ctx.measureText('ABCD').fontBoundingBoxDescent === 10;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.fontBoundingBox.ahem
+ desc: Testing fontBoundingBox for font ahem
+ test_type: promise
+ fonts:
+ - Ahem
+ code: |
+ {{ load_font }}
+ ctx.font = '50px Ahem';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert ctx.measureText('A').fontBoundingBoxAscent === 40;
+ @assert ctx.measureText('A').fontBoundingBoxDescent === 10;
+ @assert ctx.measureText('ABCD').fontBoundingBoxAscent === 40;
+ @assert ctx.measureText('ABCD').fontBoundingBoxDescent === 10;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.fontBoundingBox-reduced-ascent
+ desc: Testing fontBoundingBox for OffscreenCanvas with reduced ascent metric
+ test_type: promise
+ fonts:
+ - CanvasTest-ascent256
+ code: |
+ {{ load_font }}
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert ctx.measureText('A').fontBoundingBoxAscent === 10;
+ @assert ctx.measureText('A').fontBoundingBoxDescent === 10;
+
+ @assert ctx.measureText('ABCD').fontBoundingBoxAscent === 10;
+ @assert ctx.measureText('ABCD').fontBoundingBoxDescent === 10;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.fontBoundingBox-zero-descent
+ desc: Testing fontBoundingBox for OffscreenCanvas with zero descent metric
+ test_type: promise
+ fonts:
+ - CanvasTest-descent0
+ code: |
+ {{ load_font }}
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert ctx.measureText('A').fontBoundingBoxAscent === 30;
+ @assert ctx.measureText('A').fontBoundingBoxDescent === 0;
+
+ @assert ctx.measureText('ABCD').fontBoundingBoxAscent === 30;
+ @assert ctx.measureText('ABCD').fontBoundingBoxDescent === 0;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.emHeights
+ desc: Testing emHeights
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '40px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert ctx.measureText('A').emHeightAscent === 30;
+ @assert ctx.measureText('A').emHeightDescent === 10;
+ @assert ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent === 40;
+
+ @assert ctx.measureText('ABCD').emHeightAscent === 30;
+ @assert ctx.measureText('ABCD').emHeightDescent === 10;
+ @assert ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent === 40;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.emHeights-low-ascent
+ desc: Testing emHeights with reduced ascent metric
+ test_type: promise
+ fonts:
+ - CanvasTest-ascent256
+ code: |
+ {{ load_font }}
+ ctx.font = '40px CanvasTest-ascent256';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert ctx.measureText('A').emHeightAscent === 20;
+ @assert ctx.measureText('A').emHeightDescent === 20;
+ @assert ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent === 40;
+
+ @assert ctx.measureText('ABCD').emHeightAscent === 20;
+ @assert ctx.measureText('ABCD').emHeightDescent === 20;
+ @assert ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent === 40;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.emHeights-zero-descent
+ desc: Testing emHeights with zero descent metric
+ test_type: promise
+ fonts:
+ - CanvasTest-descent0
+ code: |
+ {{ load_font }}
+ ctx.font = '40px CanvasTest-descent0';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert ctx.measureText('A').emHeightAscent === 40;
+ @assert ctx.measureText('A').emHeightDescent === 0;
+ @assert ctx.measureText('A').emHeightDescent + ctx.measureText('A').emHeightAscent === 40;
+
+ @assert ctx.measureText('ABCD').emHeightAscent === 40;
+ @assert ctx.measureText('ABCD').emHeightDescent === 0;
+ @assert ctx.measureText('ABCD').emHeightDescent + ctx.measureText('ABCD').emHeightAscent === 40;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.measure.baselines
+ desc: Testing baselines
+ test_type: promise
+ fonts:
+ - CanvasTest
+ code: |
+ {{ load_font }}
+ ctx.font = '50px CanvasTest';
+ ctx.direction = 'ltr';
+ ctx.align = 'left'
+ @assert Math.abs(ctx.measureText('A').alphabeticBaseline) === 0;
+ @assert ctx.measureText('A').ideographicBaseline === 6.25;
+ @assert ctx.measureText('A').hangingBaseline === 25;
+
+ @assert Math.abs(ctx.measureText('ABCD').alphabeticBaseline) === 0;
+ @assert ctx.measureText('ABCD').ideographicBaseline === 6.25;
+ @assert ctx.measureText('ABCD').hangingBaseline === 25;
+ variants: *load-font-variant-definition
+
+- name: 2d.text.drawing.style.absolute.spacing
+ desc: Testing letter spacing and word spacing with absolute length
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+
+ ctx.letterSpacing = '3px';
+ @assert ctx.letterSpacing === '3px';
+ @assert ctx.wordSpacing === '0px';
+
+ ctx.wordSpacing = '5px';
+ @assert ctx.letterSpacing === '3px';
+ @assert ctx.wordSpacing === '5px';
+
+ ctx.letterSpacing = '-1px';
+ ctx.wordSpacing = '-1px';
+ @assert ctx.letterSpacing === '-1px';
+ @assert ctx.wordSpacing === '-1px';
+
+ ctx.letterSpacing = '1PX';
+ ctx.wordSpacing = '10PX';
+ @assert ctx.letterSpacing === '1px';
+ @assert ctx.wordSpacing === '10px';
+
+- name: 2d.text.drawing.style.font-relative.spacing
+ desc: Testing letter spacing and word spacing with font-relative length
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+
+ ctx.letterSpacing = '1EX';
+ ctx.wordSpacing = '1EM';
+ @assert ctx.letterSpacing === '1ex';
+ @assert ctx.wordSpacing === '1em';
+
+ ctx.letterSpacing = '1ch';
+ ctx.wordSpacing = '1ic';
+ @assert ctx.letterSpacing === '1ch';
+ @assert ctx.wordSpacing === '1ic';
+
+- name: 2d.text.drawing.style.nonfinite.spacing
+ desc: Testing letter spacing and word spacing with nonfinite inputs
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ @assert ctx.wordSpacing === '0px';
+ @assert ctx.letterSpacing === '0px';
+ }
+ @nonfinite test_word_spacing(<0 NaN Infinity -Infinity>);
+
+- name: 2d.text.drawing.style.invalid.spacing
+ desc: Testing letter spacing and word spacing with invalid units
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+
+ function test_word_spacing(value) {
+ ctx.wordSpacing = value;
+ ctx.letterSpacing = value;
+ @assert ctx.wordSpacing === '0px';
+ @assert ctx.letterSpacing === '0px';
+ }
+ @nonfinite test_word_spacing(< '0s' '1min' '1deg' '1pp' 'initial' 'inherit' 'normal' 'none'>);
+
+- name: 2d.text.drawing.style.letterSpacing.measure
+ desc: Testing letter spacing with different length units
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+ var width_normal = ctx.measureText('Hello World').width;
+
+ function test_letter_spacing(value, difference_spacing, epsilon) {
+ ctx.letterSpacing = value;
+ @assert ctx.letterSpacing === value;
+ @assert ctx.wordSpacing === '0px';
+ width_with_letter_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_letter_spacing, width_normal + difference_spacing, epsilon, "letter spacing doesn't work.");
+ }
+
+ // The first value is the letter Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 11 letters
+ // in 'hello world', so the length difference is always letterSpacing * 11.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 33, 0.1],
+ ['5px', 55, 0.1],
+ ['-2px', -22, 0.1],
+ ['1em', 110, 0.1],
+ ['-0.1em', -11, 0.1],
+ ['1in', 1056, 0.1],
+ ['-0.1cm', -41.65, 0.2],
+ ['-0.6mm', -24,95, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_letter_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+
+- name: 2d.text.drawing.style.wordSpacing.measure
+ desc: Testing word spacing with different length units
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ function test_word_spacing(value, difference_spacing, epsilon) {
+ ctx.wordSpacing = value;
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === value;
+ width_with_word_spacing = ctx.measureText('Hello World, again').width;
+ assert_approx_equals(width_with_word_spacing, width_normal + difference_spacing, epsilon, "word spacing doesn't work.");
+ }
+
+ // The first value is the word Spacing to be set, the second value the
+ // change in length of string 'Hello World', note that there are 2 words
+ // in 'Hello World, again', so the length difference is always wordSpacing * 2.
+ // and the third value is the acceptable differencee for the length change,
+ // note that unit such as 1cm/1mm doesn't map to an exact pixel value.
+ test_cases = [['3px', 6, 0.1],
+ ['5px', 10, 0.1],
+ ['-2px', -4, 0.1],
+ ['1em', 20, 0.1],
+ ['-0.5em', -10, 0.1],
+ ['1in', 192, 0.1],
+ ['-0.1cm', -7.57, 0.2],
+ ['-0.6mm', -4.54, 0.2]]
+
+ for (const test_case of test_cases) {
+ test_word_spacing(test_case[0], test_case[1], test_case[2]);
+ }
+
+- name: 2d.text.drawing.style.letterSpacing.change.font
+ desc: Set letter spacing and word spacing to font dependent value and verify it works after font change.
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+ // Get the width for 'Hello World' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World').width;
+
+ ctx.letterSpacing = '1em';
+ @assert ctx.letterSpacing === '1em';
+ // 1em = 10px. Add 10px after each letter in "Hello World",
+ // makes it 110px longer.
+ var width_with_spacing = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
+
+ // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
+ // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World').width;
+ // Now calculate the reference spacing for "Hello World" with no spacing.
+ ctx.letterSpacing = '0em';
+ width_normal = ctx.measureText('Hello World').width;
+ assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
+
+- name: 2d.text.drawing.style.wordSpacing.change.font
+ desc: Set word spacing and word spacing to font dependent value and verify it works after font change.
+ code: |
+ @assert ctx.letterSpacing === '0px';
+ @assert ctx.wordSpacing === '0px';
+ // Get the width for 'Hello World, again' at default size, 10px.
+ var width_normal = ctx.measureText('Hello World, again').width;
+
+ ctx.wordSpacing = '1em';
+ @assert ctx.wordSpacing === '1em';
+ // 1em = 10px. Add 10px after each word in "Hello World, again",
+ // makes it 20px longer.
+ var width_with_spacing = ctx.measureText('Hello World, again').width;
+ @assert width_with_spacing === width_normal + 20;
+
+ // Changing font to 20px. Without resetting the spacing, 1em wordSpacing
+ // is now 20px, so it's suppose to be 40px longer without any wordSpacing set.
+ ctx.font = '20px serif';
+ width_with_spacing = ctx.measureText('Hello World, again').width;
+ // Now calculate the reference spacing for "Hello World, again" with no spacing.
+ ctx.wordSpacing = '0em';
+ width_normal = ctx.measureText('Hello World, again').width;
+ @assert width_with_spacing === width_normal + 40;
+
+- name: 2d.text.drawing.style.fontKerning
+ desc: Testing basic functionalities of fontKerning for canvas
+ code: |
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "normal";
+ @assert ctx.fontKerning === "normal";
+ width_normal = ctx.measureText("TAWATAVA").width;
+ ctx.fontKerning = "none";
+ @assert ctx.fontKerning === "none";
+ width_none = ctx.measureText("TAWATAVA").width;
+ @assert width_normal < width_none;
+
+- name: 2d.text.drawing.style.fontKerning.with.uppercase
+ desc: Testing basic functionalities of fontKerning for canvas
+ code: |
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "Normal";
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "normal";
+ @assert ctx.fontKerning === "normal";
+ ctx.fontKerning = "Auto";
+ @assert ctx.fontKerning === "normal";
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "noRmal";
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NoRMal";
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NORMAL";
+ @assert ctx.fontKerning === "auto";
+
+ ctx.fontKerning = "None";
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "none";
+ @assert ctx.fontKerning === "none";
+ ctx.fontKerning = "Auto";
+ @assert ctx.fontKerning === "none";
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nOne";
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "nonE";
+ @assert ctx.fontKerning === "auto";
+ ctx.fontKerning = "auto";
+ ctx.fontKerning = "NONE";
+ @assert ctx.fontKerning === "auto";
+
+- name: 2d.text.drawing.style.fontVariant.settings
+ desc: Testing basic functionalities of fontVariant for canvas
+ code: |
+ // Setting fontVariantCaps with lower cases
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "normal";
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "small-caps";
+ @assert ctx.fontVariantCaps === "small-caps";
+
+ ctx.fontVariantCaps = "all-small-caps";
+ @assert ctx.fontVariantCaps === "all-small-caps";
+
+ ctx.fontVariantCaps = "petite-caps";
+ @assert ctx.fontVariantCaps === "petite-caps";
+
+ ctx.fontVariantCaps = "all-petite-caps";
+ @assert ctx.fontVariantCaps === "all-petite-caps";
+
+ ctx.fontVariantCaps = "unicase";
+ @assert ctx.fontVariantCaps === "unicase";
+
+ ctx.fontVariantCaps = "titling-caps";
+ @assert ctx.fontVariantCaps === "titling-caps";
+
+ // Setting fontVariantCaps with mixed-case values is not valid
+ ctx.fontVariantCaps = "nORmal";
+ @assert ctx.fontVariantCaps === "titling-caps";
+
+ ctx.fontVariantCaps = "normal";
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "smaLL-caps";
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "all-small-CAPS";
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "pEtitE-caps";
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "All-Petite-Caps";
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "uNIcase";
+ @assert ctx.fontVariantCaps === "normal";
+
+ ctx.fontVariantCaps = "titling-CAPS";
+ @assert ctx.fontVariantCaps === "normal";
+
+ // Setting fontVariantCaps with non-existing font variant.
+ ctx.fontVariantCaps = "titling-caps";
+ ctx.fontVariantCaps = "abcd";
+ @assert ctx.fontVariantCaps === "titling-caps";
+
+- name: 2d.text.drawing.style.textRendering.settings
+ desc: Testing basic functionalities of textRendering in Canvas
+ code: |
+ // Setting textRendering with correct case.
+ @assert ctx.textRendering === "auto";
+
+ ctx.textRendering = "optimizeSpeed";
+ @assert ctx.textRendering === "optimizeSpeed";
+
+ ctx.textRendering = "optimizeLegibility";
+ @assert ctx.textRendering === "optimizeLegibility";
+
+ ctx.textRendering = "geometricPrecision";
+ @assert ctx.textRendering === "geometricPrecision";
+
+ ctx.textRendering = "auto";
+ @assert ctx.textRendering === "auto";
+
+ // Setting textRendering with incorrect case is ignored.
+ ctx.textRendering = "OPtimizeSpeed";
+ @assert ctx.textRendering === "auto";
+
+ ctx.textRendering = "OPtimizELEgibility";
+ @assert ctx.textRendering === "auto";
+
+ ctx.textRendering = "GeometricPrecision";
+ @assert ctx.textRendering === "auto";
+
+ ctx.textRendering = "optimizespeed";
+ @assert ctx.textRendering === "auto";
+
+ ctx.textRendering = "optimizelegibility";
+ @assert ctx.textRendering === "auto";
+
+ ctx.textRendering = "geometricprecision";
+ @assert ctx.textRendering === "auto";
+
+ ctx.textRendering = "optimizeLegibility";
+ @assert ctx.textRendering === "optimizeLegibility";
+
+ ctx.textRendering = "AUTO";
+ @assert ctx.textRendering === "optimizeLegibility";
+
+ ctx.textRendering = "Auto";
+ @assert ctx.textRendering === "optimizeLegibility";
+
+ // Setting textRendering with non-existing font variant.
+ ctx.textRendering = "abcd";
+ @assert ctx.textRendering === "optimizeLegibility";
+
+ ctx.textRendering = "normal";
+ @assert ctx.textRendering === "optimizeLegibility";
+
+ ctx.textRendering = "";
+ @assert ctx.textRendering === "optimizeLegibility";
+
+ ctx.textRendering = "auto";
+ @assert ctx.textRendering === "auto";
+
+- name: 2d.text.drawing.style.fontStretch.settings
+ desc: Testing value setting of fontStretch in Canvas
+ code: |
+ // Setting textRendering with lower cases
+ ctx.fontStretch = "ultra-condensed";
+ @assert ctx.fontStretch === "ultra-condensed";
+
+ ctx.fontStretch = "extra-condensed";
+ @assert ctx.fontStretch === "extra-condensed";
+
+ ctx.fontStretch = "condensed";
+ @assert ctx.fontStretch === "condensed";
+
+ ctx.fontStretch = "semi-condensed";
+ @assert ctx.fontStretch === "semi-condensed";
+
+ ctx.fontStretch = "normal";
+ @assert ctx.fontStretch === "normal";
+
+ ctx.fontStretch = "semi-expanded";
+ @assert ctx.fontStretch === "semi-expanded";
+
+ ctx.fontStretch = "expanded";
+ @assert ctx.fontStretch === "expanded";
+
+ ctx.fontStretch = "extra-expanded";
+ @assert ctx.fontStretch === "extra-expanded";
+
+ ctx.fontStretch = "ultra-expanded";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ // Setting fontStretch with lower cases and upper cases word,
+ // these values should be ignored.
+ ctx.fontStretch = "ulTra-condensed";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "Extra-condensed";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "cOndensed";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "Semi-Condensed";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "normaL";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "semi-Expanded";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "Expanded";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "eXtra-expanded";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+ ctx.fontStretch = "abcd";
+ @assert ctx.fontStretch === "ultra-expanded";
+
+- name: 2d.text.fontVariantCaps1
+ desc: Testing small caps setting in fontVariant
+ code: |
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "small-caps";
+ // This should render the same as font = "small-caps 32px serif".
+ ctx.fillText("Hello World", 20, 100);
+ reference: |
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("Hello World", 20, 100);
+
+- name: 2d.text.fontVariantCaps2
+ desc: Testing small caps setting in fontVariant
+ code: |
+ ctx.font = "small-caps 32px serif";
+ // "mismatch" test, to verify that small-caps does change the rendering.
+ smallCaps_len = ctx.measureText("Hello World").width;
+
+ ctx.font = "32px serif";
+ normalCaps_len = ctx.measureText("Hello World").width;
+ @assert smallCaps_len != normalCaps_len;
+
+- name: 2d.text.fontVariantCaps3
+ desc: Testing small caps setting in fontVariant
+ code: |
+ ctx.font = "32px serif";
+ ctx.fontVariantCaps = "all-small-caps";
+ // This should render the same as using font = "small-caps 32px serif"
+ // with all the underlying text in lowercase.
+ ctx.fillText("Hello World", 20, 100);
+ reference: |
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("hello world", 20, 100);
+
+- name: 2d.text.fontVariantCaps4
+ desc: Testing small caps setting in fontVariant
+ code: |
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps overrides the small-caps setting from the font attribute
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.fillText("Hello World", 20, 100);
+ reference: |
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("hello world", 20, 100);
+
+- name: 2d.text.fontVariantCaps5
+ desc: Testing small caps setting in fontVariant
+ code: |
+ ctx.font = "small-caps 32px serif";
+ // fontVariantCaps 'normal' does not override the setting from the font attribute.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "normal";
+ ctx.fillText("Hello World", 20, 100);
+ reference: |
+ ctx.font = "small-caps 32px serif";
+ ctx.fillText("Hello World", 20, 100);
+
+- name: 2d.text.fontVariantCaps6
+ desc: Testing small caps setting in fontVariant
+ code: |
+ // fontVariantCaps is reset when the font attribute is set.
+ // (spec unclear, cf. https://github.com/whatwg/html/issues/8103)
+ ctx.fontVariantCaps = "all-small-caps";
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+ reference: |
+ ctx.font = "32px serif";
+ ctx.fillText("Hello World", 20, 100);
+
+- name: 2d.text.setFont.mathFont
+ desc: crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font
+ code: |
+ ctx.font = "math serif";
+
+# TODO: shadows, alpha, composite, clip
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/the-canvas-state.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/the-canvas-state.yaml
new file mode 100644
index 0000000000..0452086154
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/the-canvas-state.yaml
@@ -0,0 +1,89 @@
+- name: 2d.state.saverestore.transformation
+ desc: save()/restore() affects the current transformation matrix
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.translate(200, 0);
+ ctx.restore();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(-200, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.state.saverestore.clip
+ desc: save()/restore() affects the clipping path
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.state.saverestore.path
+ desc: save()/restore() does not affect the current path
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 100, 50);
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.state.saverestore.bitmap
+ desc: save()/restore() does not affect the current bitmap
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.state.saverestore.stack
+ desc: save()/restore() can be nested as a stack
+ code: |
+ ctx.lineWidth = 1;
+ ctx.save();
+ ctx.lineWidth = 2;
+ ctx.save();
+ ctx.lineWidth = 3;
+ @assert ctx.lineWidth === 3;
+ ctx.restore();
+ @assert ctx.lineWidth === 2;
+ ctx.restore();
+ @assert ctx.lineWidth === 1;
+
+- name: 2d.state.saverestore.stackdepth
+ desc: save()/restore() stack depth is not unreasonably limited
+ code: |
+ var limit = 512;
+ for (var i = 1; i < limit; ++i)
+ {
+ ctx.save();
+ ctx.lineWidth = i;
+ }
+ for (var i = limit-1; i > 0; --i)
+ {
+ @assert ctx.lineWidth === i;
+ ctx.restore();
+ }
+
+- name: 2d.state.saverestore.underflow
+ desc: restore() with an empty stack has no effect
+ code: |
+ for (var i = 0; i < 16; ++i)
+ ctx.restore();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ @assert ctx.lineWidth === 0.5;
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/transformations.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/transformations.yaml
new file mode 100644
index 0000000000..0d2265be7a
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/transformations.yaml
@@ -0,0 +1,356 @@
+- name: 2d.transformation.order
+ desc: Transformations are applied in the right order
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 1);
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -50, 50, 50);
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.transformation.scale.basic
+ desc: scale() works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 4);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 12.5);
+ @assert pixel 90,40 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.scale.zero
+ desc: scale() with a scale factor of zero works
+ code: |
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.scale(0, 1);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.translate(0, 25);
+ ctx.scale(1, 0);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.scale.negative
+ desc: scale() with negative scale factors works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.scale(-1, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.scale(1, -1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, -50, 50, 50);
+ ctx.restore();
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.scale.large
+ desc: scale() with large scale factors works
+ notes: Not really that large at all, but it hits the limits in Firefox.
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(1e5, 1e5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 1, 1);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.scale.nonfinite
+ desc: scale() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ @nonfinite ctx.scale(<0.1 Infinity -Infinity NaN>, <0.1 Infinity -Infinity NaN>);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.scale.multiple
+ desc: Multiple scale()s combine
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ @assert pixel 90,40 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.transformation.rotate.zero
+ desc: rotate() by 0 does nothing
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.rotate.radians
+ desc: rotate() uses radians
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.rotate.direction
+ desc: rotate() is clockwise
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -100, 50, 100);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.rotate.wrap
+ desc: rotate() wraps large positive values correctly
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi)
+ // We need about pi +/- 0.001 in order to get correct-looking results
+ // 32-bit floats can store pi*4097 with precision 2^-10, so that should
+ // be safe enough on reasonable implementations
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,2 == 0,255,0,255;
+ @assert pixel 98,47 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.rotate.wrapnegative
+ desc: rotate() wraps large negative values correctly
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(-Math.PI * (1 + 4096));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ @assert pixel 98,2 == 0,255,0,255;
+ @assert pixel 98,47 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.rotate.nonfinite
+ desc: rotate() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ @nonfinite ctx.rotate(<0.1 Infinity -Infinity NaN>);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.translate.basic
+ desc: translate() works
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ @assert pixel 90,40 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.translate.nonfinite
+ desc: translate() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ @nonfinite ctx.translate(<0.1 Infinity -Infinity NaN>, <0.1 Infinity -Infinity NaN>);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+
+- name: 2d.transformation.transform.identity
+ desc: transform() with the identity matrix does nothing
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,0, 0,1, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.transform.skewed
+ desc: transform() with skewy matrix transforms correctly
+ code: |
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.transform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ @assert pixel 21,11 == 0,255,0,255;
+ @assert pixel 79,11 == 0,255,0,255;
+ @assert pixel 21,39 == 0,255,0,255;
+ @assert pixel 79,39 == 0,255,0,255;
+ @assert pixel 39,19 == 0,255,0,255;
+ @assert pixel 61,19 == 0,255,0,255;
+ @assert pixel 39,31 == 0,255,0,255;
+ @assert pixel 61,31 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.transform.multiply
+ desc: transform() multiplies the CTM
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,2, 3,4, 5,6);
+ ctx.transform(-2,1, 3/2,-1/2, 1,-2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.transform.nonfinite
+ desc: transform() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ @nonfinite ctx.transform(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.setTransform.skewed
+ code: |
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.setTransform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ @assert pixel 21,11 == 0,255,0,255;
+ @assert pixel 79,11 == 0,255,0,255;
+ @assert pixel 21,39 == 0,255,0,255;
+ @assert pixel 79,39 == 0,255,0,255;
+ @assert pixel 39,19 == 0,255,0,255;
+ @assert pixel 61,19 == 0,255,0,255;
+ @assert pixel 39,31 == 0,255,0,255;
+ @assert pixel 61,31 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.setTransform.multiple
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.setTransform(1/2,0, 0,1/2, 0,0);
+ ctx.setTransform();
+ ctx.setTransform(2,0, 0,2, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ @assert pixel 75,35 == 0,255,0,255;
+ expected: green
+
+- name: 2d.transformation.setTransform.nonfinite
+ desc: setTransform() with Infinity/NaN is ignored
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ @nonfinite ctx.setTransform(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml
new file mode 100644
index 0000000000..f9b48fb8da
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/video.yaml
@@ -0,0 +1,10 @@
+- name: 2d.video.invalid
+ desc: Verify test doesn't crash with invalid video.
+ canvasType:
+ ['HTMLCanvas']
+ code: |
+ var v = document.createElement('video');
+ v.play();
+ // Test is deliberately not waiting for the 'playing' event to fire.
+ ctx.createPattern(v, 'repeat-x');
+ ctx.drawImage(v, 0, 0);
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml/element/meta.yaml b/testing/web-platform/tests/html/canvas/tools/yaml/element/meta.yaml
new file mode 100644
index 0000000000..5fd8b68498
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml/element/meta.yaml
@@ -0,0 +1,539 @@
+- meta: |
+ cases = [
+ ("zero", "0", 0),
+ ("empty", "", None),
+ ("onlyspace", " ", None),
+ ("space", " 100", 100),
+ ("whitespace", "\r\n\t\f100", 100),
+ ("plus", "+100", 100),
+ ("minus", "-100", None),
+ ("octal", "0100", 100),
+ ("hex", "0x100", 0),
+ ("exp", "100e1", 100),
+ ("decimal", "100.999", 100),
+ ("percent", "100%", 100),
+ ("em", "100em", 100),
+ ("junk", "#!?", None),
+ ("trailingjunk", "100#!?", 100),
+ ]
+ def gen(name, string, exp, code):
+ if exp is None:
+ code += "@assert canvas.width === 300;\n@assert canvas.height === 150;\n"
+ expected = "size 300 150"
+ else:
+ code += "@assert canvas.width === %s;\n@assert canvas.height === %s;\n" % (exp, exp)
+ expected = "size %s %s" % (exp, exp)
+
+ # With "100%", Opera gets canvas.width = 100 but renders at 100% of the frame width,
+ # so check the CSS display width
+ code += '@assert window.getComputedStyle(canvas, null).getPropertyValue("width") === "%spx";\n' % (exp, )
+
+ code += "@assert canvas.getAttribute('width') === %r;\n" % string
+ code += "@assert canvas.getAttribute('height') === %r;\n" % string
+
+ if exp == 0:
+ expected = None # can't generate zero-sized PNGs for the expected image
+
+ return code, expected
+
+ for name, string, exp in cases:
+ code = ""
+ code, expected = gen(name, string, exp, code)
+ # We need to replace \r with &#xD; because \r\n gets converted to \n in the HTML parser.
+ htmlString = string.replace('\r', '&#xD;')
+ tests.append( {
+ "name": "2d.canvas.host.size.attributes.parse.%s" % name,
+ "desc": "Parsing of non-negative integers",
+ "size": '%s, %s' % (htmlString, htmlString),
+ "code": code,
+ "expected": expected
+ } )
+
+ for name, string, exp in cases:
+ code = "canvas.setAttribute('width', %r);\ncanvas.setAttribute('height', %r);\n" % (string, string)
+ code, expected = gen(name, string, exp, code)
+ tests.append( {
+ "name": "2d.canvas.host.size.attributes.setAttribute.%s" % name,
+ "desc": "Parsing of non-negative integers in setAttribute",
+ "size": '50, 50',
+ "code": code,
+ "expected": expected
+ } )
+
+- meta: |
+ state = [ # some non-default values to test with
+ ('strokeStyle', '"#ff0000"'),
+ ('fillStyle', '"#ff0000"'),
+ ('globalAlpha', 0.5),
+ ('lineWidth', 0.5),
+ ('lineCap', '"round"'),
+ ('lineJoin', '"round"'),
+ ('miterLimit', 0.5),
+ ('shadowOffsetX', 5),
+ ('shadowOffsetY', 5),
+ ('shadowBlur', 5),
+ ('shadowColor', '"#ff0000"'),
+ ('globalCompositeOperation', '"copy"'),
+ ('font', '"25px serif"'),
+ ('textAlign', '"center"'),
+ ('textBaseline', '"bottom"'),
+ ]
+ for key,value in state:
+ tests.append( {
+ 'name': '2d.state.saverestore.%s' % key,
+ 'desc': 'save()/restore() works for %s' % key,
+ 'code':
+ """// Test that restore() undoes any modifications
+ var old = ctx.%(key)s;
+ ctx.save();
+ ctx.%(key)s = %(value)s;
+ ctx.restore();
+ @assert ctx.%(key)s === old;
+
+ // Also test that save() doesn't modify the values
+ ctx.%(key)s = %(value)s;
+ old = ctx.%(key)s;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against %(value)s
+ ctx.save();
+ @assert ctx.%(key)s === old;
+ ctx.restore();
+ """ % { 'key':key, 'value':value }
+ } )
+
+ tests.append( {
+ 'name': '2d.canvas.host.initial.reset.2dstate',
+ 'desc': 'Resetting the canvas state resets 2D state variables',
+ 'code':
+ """canvas.width = 100;
+ var default_val;
+ """ + "".join(
+ """
+ default_val = ctx.%(key)s;
+ ctx.%(key)s = %(value)s;
+ canvas.width = 100;
+ @assert ctx.%(key)s === default_val;
+ """ % { 'key':key, 'value':value }
+ for key,value in state),
+ } )
+
+- meta: |
+ # Composite operation tests
+ # <http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2007-March/010608.html>
+ ops = [
+ # name FA FB
+ ('source-over', '1', '1-aA'),
+ ('destination-over', '1-aB', '1'),
+ ('source-in', 'aB', '0'),
+ ('destination-in', '0', 'aA'),
+ ('source-out', '1-aB', '0'),
+ ('destination-out', '0', '1-aA'),
+ ('source-atop', 'aB', '1-aA'),
+ ('destination-atop', '1-aB', 'aA'),
+ ('xor', '1-aB', '1-aA'),
+ ('copy', '1', '0'),
+ ('lighter', '1', '1'),
+ ('clear', '0', '0'),
+ ]
+
+ # The ones that change the output when src = (0,0,0,0):
+ ops_trans = [ 'source-in', 'destination-in', 'source-out', 'destination-atop', 'copy' ];
+
+ def calc_output(A, B, FA_code, FB_code):
+ (RA, GA, BA, aA) = A
+ (RB, GB, BB, aB) = B
+ rA, gA, bA = RA*aA, GA*aA, BA*aA
+ rB, gB, bB = RB*aB, GB*aB, BB*aB
+
+ FA = eval(FA_code)
+ FB = eval(FB_code)
+
+ rO = rA*FA + rB*FB
+ gO = gA*FA + gB*FB
+ bO = bA*FA + bB*FB
+ aO = aA*FA + aB*FB
+
+ rO = min(255, rO)
+ gO = min(255, gO)
+ bO = min(255, bO)
+ aO = min(1, aO)
+
+ if aO:
+ RO = rO / aO
+ GO = gO / aO
+ BO = bO / aO
+ else: RO = GO = BO = 0
+
+ return (RO, GO, BO, aO)
+
+ def to_test(color):
+ r, g, b, a = color
+ return '%d,%d,%d,%d' % (round(r), round(g), round(b), round(a*255))
+ def to_cairo(color):
+ r, g, b, a = color
+ return '%f,%f,%f,%f' % (r/255., g/255., b/255., a)
+
+ for (name, src, dest) in [
+ ('solid', (255, 255, 0, 1.0), (0, 255, 255, 1.0)),
+ ('transparent', (0, 0, 255, 0.75), (0, 255, 0, 0.5)),
+ # catches the atop, xor and lighter bugs in Opera 9.10
+ ]:
+ for op, FA_code, FB_code in ops:
+ expected = calc_output(src, dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ """ % (dest, op, src, to_test(expected)),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%s)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % to_cairo(expected),
+ } )
+
+ for (name, src, dest) in [ ('image', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ expected = calc_output(src, dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'images': [ 'yellow75.png' ],
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ """ % (dest, op, to_test(expected)),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%s)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % to_cairo(expected),
+ } )
+
+ for (name, src, dest) in [ ('canvas', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ expected = calc_output(src, dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'images': [ 'yellow75.png' ],
+ 'code': """
+ var canvas2 = document.createElement('canvas');
+ canvas2.width = canvas.width;
+ canvas2.height = canvas.height;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0);
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.drawImage(canvas2, 0, 0);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ """ % (dest, op, to_test(expected)),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%s)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % to_cairo(expected),
+ } )
+
+
+ for (name, src, dest) in [ ('uncovered.fill', (0, 0, 255, 0.75), (0, 255, 0, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.fillStyle = 'rgba%s';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ """ % (dest, op, src, to_test(expected0)),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%s)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % (to_cairo(expected0)),
+ } )
+
+ for (name, src, dest) in [ ('uncovered.image', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'images': [ 'yellow.png' ],
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.drawImage(document.getElementById('yellow.png'), 40, 40, 10, 10, 40, 50, 10, 10);
+ @assert pixel 15,15 ==~ %s +/- 5;
+ @assert pixel 50,25 ==~ %s +/- 5;
+ """ % (dest, op, to_test(expected0), to_test(expected0)),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%s)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % (to_cairo(expected0)),
+ } )
+
+ for (name, src, dest) in [ ('uncovered.nocontext', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ var canvas2 = document.createElement('canvas');
+ ctx.drawImage(canvas2, 0, 0);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ """ % (dest, op, to_test(expected0)),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%s)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % (to_cairo(expected0)),
+ } )
+
+ for (name, src, dest) in [ ('uncovered.pattern', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'images': [ 'yellow.png' ],
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.fillStyle = ctx.createPattern(document.getElementById('yellow.png'), 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ """ % (dest, op, to_test(expected0)),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%s)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % (to_cairo(expected0)),
+ } )
+
+ for op, FA_code, FB_code in ops:
+ tests.append( {
+ 'name': '2d.composite.clip.%s' % (op),
+ 'desc': 'fill() does not affect pixels outside the clip region.',
+ 'code': """
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ """ % (op),
+ 'expected': 'green'
+ } )
+
+- meta: |
+ # Color parsing tests
+
+ # Try most of the CSS3 Color <color> values - http://www.w3.org/TR/css3-color/#colorunits
+ big_float = '1' + ('0' * 39)
+ big_double = '1' + ('0' * 310)
+ for name, string, r,g,b,a, notes in [
+ ('html4', 'limE', 0,255,0,255, ""),
+ ('hex3', '#0f0', 0,255,0,255, ""),
+ ('hex4', '#0f0f', 0,255,0,255, ""),
+ ('hex6', '#00fF00', 0,255,0,255, ""),
+ ('hex8', '#00ff00ff', 0,255,0,255, ""),
+ ('rgb-num', 'rgb(0,255,0)', 0,255,0,255, ""),
+ ('rgb-clamp-1', 'rgb(-1000, 1000, -1000)', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-2', 'rgb(-200%, 200%, -200%)', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-3', 'rgb(-2147483649, 4294967298, -18446744073709551619)', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-4', 'rgb(-'+big_float+', '+big_float+', -'+big_float+')', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-5', 'rgb(-'+big_double+', '+big_double+', -'+big_double+')', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-percent', 'rgb(0% ,100% ,0%)', 0,255,0,255, 'CSS3 Color says "The integer value 255 corresponds to 100%". (In particular, it is not 254...)'),
+ ('rgb-eof', 'rgb(0, 255, 0', 0,255,0,255, ""), # see CSS2.1 4.2 "Unexpected end of style sheet"
+ ('rgba-solid-1', 'rgba( 0 , 255 , 0 , 1 )', 0,255,0,255, ""),
+ ('rgba-solid-2', 'rgba( 0 , 255 , 0 , 1.0 )', 0,255,0,255, ""),
+ ('rgba-solid-3', 'rgba( 0 , 255 , 0 , +1 )', 0,255,0,255, ""),
+ ('rgba-solid-4', 'rgba( -0 , 255 , +0 , 1 )', 0,255,0,255, ""),
+ ('rgba-num-1', 'rgba( 0 , 255 , 0 , .499 )', 0,255,0,127, ""),
+ ('rgba-num-2', 'rgba( 0 , 255 , 0 , 0.499 )', 0,255,0,127, ""),
+ ('rgba-percent', 'rgba(0%,100%,0%,0.499)', 0,255,0,127, ""), # 0.499*255 rounds to 127, both down and nearest, so it should be safe
+ ('rgba-clamp-1', 'rgba(0, 255, 0, -2)', 0,0,0,0, ""),
+ ('rgba-clamp-2', 'rgba(0, 255, 0, 2)', 0,255,0,255, ""),
+ ('rgba-eof', 'rgba(0, 255, 0, 1', 0,255,0,255, ""),
+ ('transparent-1', 'transparent', 0,0,0,0, ""),
+ ('transparent-2', 'TrAnSpArEnT', 0,0,0,0, ""),
+ ('hsl-1', 'hsl(120, 100%, 50%)', 0,255,0,255, ""),
+ ('hsl-2', 'hsl( -240 , 100% , 50% )', 0,255,0,255, ""),
+ ('hsl-3', 'hsl(360120, 100%, 50%)', 0,255,0,255, ""),
+ ('hsl-4', 'hsl(-360240, 100%, 50%)', 0,255,0,255, ""),
+ ('hsl-5', 'hsl(120.0, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('hsl-6', 'hsl(+120, +100%, +50%)', 0,255,0,255, ""),
+ ('hsl-clamp-1', 'hsl(120, 200%, 50%)', 0,255,0,255, ""),
+ ('hsl-clamp-2', 'hsl(120, -200%, 49.9%)', 127,127,127,255, ""),
+ ('hsl-clamp-3', 'hsl(120, 100%, 200%)', 255,255,255,255, ""),
+ ('hsl-clamp-4', 'hsl(120, 100%, -200%)', 0,0,0,255, ""),
+ ('hsla-1', 'hsla(120, 100%, 50%, 0.499)', 0,255,0,127, ""),
+ ('hsla-2', 'hsla( 120.0 , 100.0% , 50.0% , 1 )', 0,255,0,255, ""),
+ ('hsla-clamp-1', 'hsla(120, 200%, 50%, 1)', 0,255,0,255, ""),
+ ('hsla-clamp-2', 'hsla(120, -200%, 49.9%, 1)', 127,127,127,255, ""),
+ ('hsla-clamp-3', 'hsla(120, 100%, 200%, 1)', 255,255,255,255, ""),
+ ('hsla-clamp-4', 'hsla(120, 100%, -200%, 1)', 0,0,0,255, ""),
+ ('hsla-clamp-5', 'hsla(120, 100%, 50%, 2)', 0,255,0,255, ""),
+ ('hsla-clamp-6', 'hsla(120, 100%, 0%, -2)', 0,0,0,0, ""),
+ ('svg-1', 'gray', 128,128,128,255, ""),
+ ('svg-2', 'grey', 128,128,128,255, ""),
+ # css-color-4 rgb() color function
+ # https://drafts.csswg.org/css-color/#numeric-rgb
+ ('css-color-4-rgb-1', 'rgb(0, 255.0, 0)', 0,255,0,255, ""),
+ ('css-color-4-rgb-2', 'rgb(0, 255, 0, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgb-3', 'rgb(0, 255, 0, 20%)', 0,255,0,51, ""),
+ ('css-color-4-rgb-4', 'rgb(0 255 0)', 0,255,0,255, ""),
+ ('css-color-4-rgb-5', 'rgb(0 255 0 / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgb-6', 'rgb(0 255 0 / 20%)', 0,255,0,51, ""),
+ ('css-color-4-rgba-1', 'rgba(0, 255.0, 0)', 0,255,0,255, ""),
+ ('css-color-4-rgba-2', 'rgba(0, 255, 0, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgba-3', 'rgba(0, 255, 0, 20%)', 0,255,0,51, ""),
+ ('css-color-4-rgba-4', 'rgba(0 255 0)', 0,255,0,255, ""),
+ ('css-color-4-rgba-5', 'rgba(0 255 0 / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgba-6', 'rgba(0 255 0 / 20%)', 0,255,0,51, ""),
+ # css-color-4 hsl() color function
+ # https://drafts.csswg.org/css-color/#the-hsl-notation
+ ('css-color-4-hsl-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsl-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsl-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""),
+ ('css-color-4-hsl-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsl-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsla-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsla-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""),
+ ('css-color-4-hsla-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsla-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""),
+ # currentColor is handled later
+ ]:
+ # TODO: test by retrieving fillStyle, instead of actually drawing?
+ # TODO: test strokeStyle, shadowColor in the same way
+ test = {
+ 'name': '2d.fillStyle.parse.%s' % name,
+ 'notes': notes,
+ 'code': """
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '%s';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == %d,%d,%d,%d;
+ """ % (string, r,g,b,a),
+ 'expected': """size 100 50
+ cr.set_source_rgba(%f, %f, %f, %f)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ """ % (r/255., g/255., b/255., a/255.),
+ }
+ tests.append(test)
+
+ # Also test that invalid colors are ignored
+ for name, string in [
+ ('hex1', '#f'),
+ ('hex2', '#f0'),
+ ('hex3', '#g00'),
+ ('hex4', '#fg00'),
+ ('hex5', '#ff000'),
+ ('hex6', '#fg0000'),
+ ('hex7', '#ff0000f'),
+ ('hex8', '#fg0000ff'),
+ ('rgb-1', 'rgb(255.0, 0, 0,)'),
+ ('rgb-2', 'rgb(100%, 0, 0)'),
+ ('rgb-3', 'rgb(255, - 1, 0)'),
+ ('rgba-1', 'rgba(100%, 0, 0, 1)'),
+ ('rgba-2', 'rgba(255, 0, 0, 1. 0)'),
+ ('rgba-3', 'rgba(255, 0, 0, 1.)'),
+ ('rgba-4', 'rgba(255, 0, 0, '),
+ ('rgba-5', 'rgba(255, 0, 0, 1,)'),
+ ('hsl-1', 'hsl(0%, 100%, 50%)'),
+ ('hsl-2', 'hsl(z, 100%, 50%)'),
+ ('hsl-3', 'hsl(0, 0, 50%)'),
+ ('hsl-4', 'hsl(0, 100%, 0)'),
+ ('hsl-5', 'hsl(0, 100.%, 50%)'),
+ ('hsl-6', 'hsl(0, 100%, 50%,)'),
+ ('hsla-1', 'hsla(0%, 100%, 50%, 1)'),
+ ('hsla-2', 'hsla(0, 0, 50%, 1)'),
+ ('hsla-3', 'hsla(0, 0, 50%, 1,)'),
+ ('name-1', 'darkbrown'),
+ ('name-2', 'firebrick1'),
+ ('name-3', 'red blue'),
+ ('name-4', '"red"'),
+ ('name-5', '"red'),
+ # css-color-4 color function
+ # comma and comma-less expressions should not mix together.
+ ('css-color-4-rgb-1', 'rgb(255, 0, 0 / 1)'),
+ ('css-color-4-rgb-2', 'rgb(255 0 0, 1)'),
+ ('css-color-4-rgb-3', 'rgb(255, 0 0)'),
+ ('css-color-4-rgba-1', 'rgba(255, 0, 0 / 1)'),
+ ('css-color-4-rgba-2', 'rgba(255 0 0, 1)'),
+ ('css-color-4-rgba-3', 'rgba(255, 0 0)'),
+ ('css-color-4-hsl-1', 'hsl(0, 100%, 50% / 1)'),
+ ('css-color-4-hsl-2', 'hsl(0 100% 50%, 1)'),
+ ('css-color-4-hsl-3', 'hsl(0, 100% 50%)'),
+ ('css-color-4-hsla-1', 'hsla(0, 100%, 50% / 1)'),
+ ('css-color-4-hsla-2', 'hsla(0 100% 50%, 1)'),
+ ('css-color-4-hsla-3', 'hsla(0, 100% 50%)'),
+ # trailing slash
+ ('css-color-4-rgb-4', 'rgb(0 0 0 /)'),
+ ('css-color-4-rgb-5', 'rgb(0, 0, 0 /)'),
+ ('css-color-4-hsl-4', 'hsl(0 100% 50% /)'),
+ ('css-color-4-hsl-5', 'hsl(0, 100%, 50% /)'),
+ ]:
+ test = {
+ 'name': '2d.fillStyle.parse.invalid.%s' % name,
+ 'code': """
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '%s'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ """ % string,
+ 'expected': 'green'
+ }
+ tests.append(test)
+
+ # Some can't have positive tests, only negative tests, because we don't know what color they're meant to be
+ for name, string in [
+ ('system', 'ThreeDDarkShadow'),
+ #('flavor', 'flavor'), # removed from latest CSS3 Color drafts
+ ]:
+ test = {
+ 'name': '2d.fillStyle.parse.%s' % name,
+ 'code': """
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '%s';
+ @assert ctx.fillStyle =~ /^#(?!(FF0000|ff0000|f00)$)/; // test that it's not red
+ """ % (string,),
+ }
+ tests.append(test) \ No newline at end of file
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml/element/the-canvas-element.yaml b/testing/web-platform/tests/html/canvas/tools/yaml/element/the-canvas-element.yaml
new file mode 100644
index 0000000000..1ecf8ccdbf
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml/element/the-canvas-element.yaml
@@ -0,0 +1,143 @@
+- name: 2d.canvas.context.exists
+ desc: The 2D context is implemented
+ code: |
+ @assert canvas.getContext('2d') !== null;
+
+- name: 2d.canvas.context.invalid.args
+ desc: Calling getContext with invalid arguments.
+ code: |
+ @assert canvas.getContext('') === null;
+ @assert canvas.getContext('2d#') === null;
+ @assert canvas.getContext('This is clearly not a valid context name.') === null;
+ @assert canvas.getContext('2d\0') === null;
+ @assert canvas.getContext('2\uFF44') === null;
+ @assert canvas.getContext('2D') === null;
+ @assert throws TypeError canvas.getContext();
+ @assert canvas.getContext('null') === null;
+ @assert canvas.getContext('undefined') === null;
+
+- name: 2d.canvas.context.extraargs.create
+ desc: The 2D context doesn't throw with extra getContext arguments (new context)
+ code: |
+ @assert document.createElement("canvas").getContext('2d', false, {}, [], 1, "2") !== null;
+ @assert document.createElement("canvas").getContext('2d', 123) !== null;
+ @assert document.createElement("canvas").getContext('2d', "test") !== null;
+ @assert document.createElement("canvas").getContext('2d', undefined) !== null;
+ @assert document.createElement("canvas").getContext('2d', null) !== null;
+ @assert document.createElement("canvas").getContext('2d', Symbol.hasInstance) !== null;
+
+- name: 2d.canvas.context.extraargs.cache
+ desc: The 2D context doesn't throw with extra getContext arguments (cached)
+ code: |
+ @assert canvas.getContext('2d', false, {}, [], 1, "2") !== null;
+ @assert canvas.getContext('2d', 123) !== null;
+ @assert canvas.getContext('2d', "test") !== null;
+ @assert canvas.getContext('2d', undefined) !== null;
+ @assert canvas.getContext('2d', null) !== null;
+ @assert canvas.getContext('2d', Symbol.hasInstance) !== null;
+
+- name: 2d.canvas.context.type.exists
+ desc: The 2D context interface is a property of 'window'
+ notes: &bindings Defined in "Web IDL" (draft)
+ code: |
+ @assert window.CanvasRenderingContext2D;
+
+- name: 2d.canvas.context.type.prototype
+ desc: window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]],
+ and its methods are [[Configurable]].
+ notes: *bindings
+ code: |
+ @assert window.CanvasRenderingContext2D.prototype;
+ @assert window.CanvasRenderingContext2D.prototype.fill;
+ window.CanvasRenderingContext2D.prototype = null;
+ @assert window.CanvasRenderingContext2D.prototype;
+ delete window.CanvasRenderingContext2D.prototype;
+ @assert window.CanvasRenderingContext2D.prototype;
+ window.CanvasRenderingContext2D.prototype.fill = 1;
+ @assert window.CanvasRenderingContext2D.prototype.fill === 1;
+ delete window.CanvasRenderingContext2D.prototype.fill;
+ @assert window.CanvasRenderingContext2D.prototype.fill === undefined;
+
+- name: 2d.canvas.context.type.replace
+ desc: Interface methods can be overridden
+ notes: *bindings
+ code: |
+ var fillRect = window.CanvasRenderingContext2D.prototype.fillRect;
+ window.CanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h)
+ {
+ this.fillStyle = '#0f0';
+ fillRect.call(this, x, y, w, h);
+ };
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.canvas.context.type.extend
+ desc: Interface methods can be added
+ notes: *bindings
+ code: |
+ window.CanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h)
+ {
+ this.fillStyle = '#0f0';
+ this.fillRect(x, y, w, h);
+ };
+ ctx.fillStyle = '#f00';
+ ctx.fillRectGreen(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.canvas.context.unique
+ desc: getContext('2d') returns the same object
+ code: |
+ @assert canvas.getContext('2d') === canvas.getContext('2d');
+
+- name: 2d.canvas.context.shared
+ desc: getContext('2d') returns objects which share canvas state
+ code: |
+ var ctx2 = canvas.getContext('2d');
+ ctx.fillStyle = '#f00';
+ ctx2.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ expected: green
+
+- name: 2d.canvas.host.scaled
+ desc: CSS-scaled canvases get drawn correctly
+ size: 50, 25
+ canvas: 'style="width: 100px; height: 50px"'
+ manual:
+ code: |
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 50, 25);
+ ctx.fillStyle = '#0ff';
+ ctx.fillRect(0, 0, 25, 10);
+ expected: |
+ size 100 50
+ cr.set_source_rgb(0, 0, 1)
+ cr.rectangle(0, 0, 100, 50)
+ cr.fill()
+ cr.set_source_rgb(0, 1, 1)
+ cr.rectangle(0, 0, 50, 20)
+ cr.fill()
+
+- name: 2d.canvas.host.reference
+ desc: CanvasRenderingContext2D.canvas refers back to its canvas
+ code: |
+ @assert ctx.canvas === canvas;
+
+- name: 2d.canvas.host.readonly
+ desc: CanvasRenderingContext2D.canvas is readonly
+ code: |
+ var c = document.createElement('canvas');
+ var d = ctx.canvas;
+ @assert c !== d;
+ ctx.canvas = c;
+ @assert ctx.canvas === d;
+
+- name: 2d.canvas.context.prototype
+ desc: checks CanvasRenderingContext2D prototype
+ code: |
+ @assert Object.getPrototypeOf(CanvasRenderingContext2D.prototype) === Object.prototype;
+ @assert Object.getPrototypeOf(ctx) === CanvasRenderingContext2D.prototype;
+ t.done();
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml/offscreen/meta.yaml b/testing/web-platform/tests/html/canvas/tools/yaml/offscreen/meta.yaml
new file mode 100644
index 0000000000..7b44fd9f26
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml/offscreen/meta.yaml
@@ -0,0 +1,539 @@
+- meta: |
+ state = [ # some non-default values to test with
+ ('strokeStyle', '"#ff0000"'),
+ ('fillStyle', '"#ff0000"'),
+ ('globalAlpha', 0.5),
+ ('lineWidth', 0.5),
+ ('lineCap', '"round"'),
+ ('lineJoin', '"round"'),
+ ('miterLimit', 0.5),
+ ('shadowOffsetX', 5),
+ ('shadowOffsetY', 5),
+ ('shadowBlur', 5),
+ ('shadowColor', '"#ff0000"'),
+ ('globalCompositeOperation', '"copy"'),
+ ]
+ for key,value in state:
+ tests.append( {
+ 'name': '2d.state.saverestore.%s' % key,
+ 'desc': 'save()/restore() works for %s' % key,
+ 'code':
+ """// Test that restore() undoes any modifications
+ var old = ctx.%(key)s;
+ ctx.save();
+ ctx.%(key)s = %(value)s;
+ ctx.restore();
+ @assert ctx.%(key)s === old;
+
+ // Also test that save() doesn't modify the values
+ ctx.%(key)s = %(value)s;
+ old = ctx.%(key)s;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against %(value)s
+ ctx.save();
+ @assert ctx.%(key)s === old;
+ ctx.restore();
+ t.done();
+ """ % { 'key':key, 'value':value }
+ } )
+
+ tests.append( {
+ 'name': '2d.canvas.host.initial.reset.2dstate',
+ 'desc': 'Resetting the canvas state resets 2D state variables',
+ 'code':
+ """canvas.width = 100;
+ var default_val;
+ """ + "".join(
+ """
+ default_val = ctx.%(key)s;
+ ctx.%(key)s = %(value)s;
+ canvas.width = 100;
+ @assert ctx.%(key)s === default_val;
+ """ % { 'key':key, 'value':value }
+ for key,value in state) + "\nt.done();",
+ } )
+
+- meta: |
+ # Composite operation tests
+ # <http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2007-March/010608.html>
+ ops = [
+ # name FA FB
+ ('source-over', '1', '1-aA'),
+ ('destination-over', '1-aB', '1'),
+ ('source-in', 'aB', '0'),
+ ('destination-in', '0', 'aA'),
+ ('source-out', '1-aB', '0'),
+ ('destination-out', '0', '1-aA'),
+ ('source-atop', 'aB', '1-aA'),
+ ('destination-atop', '1-aB', 'aA'),
+ ('xor', '1-aB', '1-aA'),
+ ('copy', '1', '0'),
+ ('lighter', '1', '1'),
+ ('clear', '0', '0'),
+ ]
+
+ # The ones that change the output when src = (0,0,0,0):
+ ops_trans = [ 'source-in', 'destination-in', 'source-out', 'destination-atop', 'copy' ];
+
+ def calc_output(A, B, FA_code, FB_code):
+ RA, GA, BA, aA = A
+ RB, GB, BB, aB = B
+ rA, gA, bA = RA*aA, GA*aA, BA*aA
+ rB, gB, bB = RB*aB, GB*aB, BB*aB
+
+ FA = eval(FA_code)
+ FB = eval(FB_code)
+
+ rO = rA*FA + rB*FB
+ gO = gA*FA + gB*FB
+ bO = bA*FA + bB*FB
+ aO = aA*FA + aB*FB
+
+ rO = min(255, rO)
+ gO = min(255, gO)
+ bO = min(255, bO)
+ aO = min(1, aO)
+
+ if aO:
+ RO = rO / aO
+ GO = gO / aO
+ BO = bO / aO
+ else: RO = GO = BO = 0
+
+ return (RO, GO, BO, aO)
+
+ def to_test(color):
+ r, g, b, a = color
+ return '%d,%d,%d,%d' % (round(r), round(g), round(b), round(a*255))
+ def to_cairo(color):
+ r, g, b, a = color
+ return '%f,%f,%f,%f' % (r/255., g/255., b/255., a)
+
+ for (name, src, dest) in [
+ ('solid', (255, 255, 0, 1.0), (0, 255, 255, 1.0)),
+ ('transparent', (0, 0, 255, 0.75), (0, 255, 0, 0.5)),
+ # catches the atop, xor and lighter bugs in Opera 9.10
+ ]:
+ for op, FA_code, FB_code in ops:
+ expected = calc_output(src, dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ t.done();
+ """ % (dest, op, src, to_test(expected)),
+ } )
+
+ for (name, src, dest) in [ ('image', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ expected = calc_output(src, dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'images': [ 'yellow75.png' ],
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 0, 0);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ });
+ }).then(t_pass, t_fail);
+ """ % (dest, op, to_test(expected)),
+ } )
+
+ for (name, src, dest) in [ ('canvas', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ expected = calc_output(src, dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'images': [ 'yellow75.png' ],
+ 'code': """
+ var offscreenCanvas2 = new OffscreenCanvas(canvas.width, canvas.height);
+ var ctx2 = offscreenCanvas2.getContext('2d');
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow75.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx2.drawImage(bitmap, 0, 0);
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ });
+ }).then(t_pass, t_fail);
+ """ % (dest, op, to_test(expected)),
+ } )
+
+ for (name, src, dest) in [ ('uncovered.fill', (0, 0, 255, 0.75), (0, 255, 0, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ new_test = {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.fillStyle = 'rgba%s';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ t.done();
+ """ % (dest, op, src, to_test(expected0)),
+ }
+ if op == 'destination-in':
+ new_test['timeout'] = 'long'
+ tests.append(new_test)
+
+ for (name, src, dest) in [ ('uncovered.image', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'images': [ 'yellow.png' ],
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.drawImage(bitmap, 40, 40, 10, 10, 40, 50, 10, 10);
+ @assert pixel 15,15 ==~ %s +/- 5;
+ @assert pixel 50,25 ==~ %s +/- 5;
+ });
+ }).then(t_pass, t_fail);
+ """ % (dest, op, to_test(expected0), to_test(expected0)),
+ } )
+
+ for (name, src, dest) in [ ('uncovered.nocontext', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ ctx.drawImage(offscreenCanvas2, 0, 0);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ t.done();
+ """ % (dest, op, to_test(expected0)),
+ } )
+
+ for (name, src, dest) in [ ('uncovered.pattern', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]:
+ for op, FA_code, FB_code in ops:
+ if op not in ops_trans: continue
+ expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code)
+ tests.append( {
+ 'name': '2d.composite.%s.%s' % (name, op),
+ 'desc': 'Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.',
+ 'images': [ 'yellow.png' ],
+ 'code': """
+ ctx.fillStyle = 'rgba%s';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ var promise = new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", '/images/yellow.png');
+ xhr.responseType = 'blob';
+ xhr.send();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ });
+ promise.then(function(response) {
+ return createImageBitmap(response).then(bitmap => {
+ ctx.fillStyle = ctx.createPattern(bitmap, 'no-repeat');
+ ctx.fillRect(0, 50, 100, 50);
+ @assert pixel 50,25 ==~ %s +/- 5;
+ });
+ }).then(t_pass, t_fail);
+ """ % (dest, op, to_test(expected0)),
+ } )
+
+ for op, FA_code, FB_code in ops:
+ tests.append( {
+ 'name': '2d.composite.clip.%s' % (op),
+ 'desc': 'fill() does not affect pixels outside the clip region.',
+ 'code': """
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = '%s';
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ @assert pixel 25,25 == 0,255,0,255;
+ @assert pixel 75,25 == 0,255,0,255;
+ t.done();
+ """ % (op),
+ } )
+
+- meta: |
+ # Color parsing tests
+
+ # Try most of the CSS3 Color <color> values - http://www.w3.org/TR/css3-color/#colorunits
+ big_float = '1' + ('0' * 39)
+ big_double = '1' + ('0' * 310)
+ for name, string, r,g,b,a, notes in [
+ ('html4', 'limE', 0,255,0,255, ""),
+ ('hex3', '#0f0', 0,255,0,255, ""),
+ ('hex4', '#0f0f', 0,255,0,255, ""),
+ ('hex6', '#00fF00', 0,255,0,255, ""),
+ ('hex8', '#00ff00ff', 0,255,0,255, ""),
+ ('rgb-num', 'rgb(0,255,0)', 0,255,0,255, ""),
+ ('rgb-clamp-1', 'rgb(-1000, 1000, -1000)', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-2', 'rgb(-200%, 200%, -200%)', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-3', 'rgb(-2147483649, 4294967298, -18446744073709551619)', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-4', 'rgb(-'+big_float+', '+big_float+', -'+big_float+')', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-clamp-5', 'rgb(-'+big_double+', '+big_double+', -'+big_double+')', 0,255,0,255, 'Assumes colors are clamped to [0,255].'),
+ ('rgb-percent', 'rgb(0% ,100% ,0%)', 0,255,0,255, 'CSS3 Color says "The integer value 255 corresponds to 100%". (In particular, it is not 254...)'),
+ ('rgb-eof', 'rgb(0, 255, 0', 0,255,0,255, ""), # see CSS2.1 4.2 "Unexpected end of style sheet"
+ ('rgba-solid-1', 'rgba( 0 , 255 , 0 , 1 )', 0,255,0,255, ""),
+ ('rgba-solid-2', 'rgba( 0 , 255 , 0 , 1.0 )', 0,255,0,255, ""),
+ ('rgba-solid-3', 'rgba( 0 , 255 , 0 , +1 )', 0,255,0,255, ""),
+ ('rgba-solid-4', 'rgba( -0 , 255 , +0 , 1 )', 0,255,0,255, ""),
+ ('rgba-num-1', 'rgba( 0 , 255 , 0 , .499 )', 0,255,0,127, ""),
+ ('rgba-num-2', 'rgba( 0 , 255 , 0 , 0.499 )', 0,255,0,127, ""),
+ ('rgba-percent', 'rgba(0%,100%,0%,0.499)', 0,255,0,127, ""), # 0.499*255 rounds to 127, both down and nearest, so it should be safe
+ ('rgba-clamp-1', 'rgba(0, 255, 0, -2)', 0,0,0,0, ""),
+ ('rgba-clamp-2', 'rgba(0, 255, 0, 2)', 0,255,0,255, ""),
+ ('rgba-eof', 'rgba(0, 255, 0, 1', 0,255,0,255, ""),
+ ('transparent-1', 'transparent', 0,0,0,0, ""),
+ ('transparent-2', 'TrAnSpArEnT', 0,0,0,0, ""),
+ ('hsl-1', 'hsl(120, 100%, 50%)', 0,255,0,255, ""),
+ ('hsl-2', 'hsl( -240 , 100% , 50% )', 0,255,0,255, ""),
+ ('hsl-3', 'hsl(360120, 100%, 50%)', 0,255,0,255, ""),
+ ('hsl-4', 'hsl(-360240, 100%, 50%)', 0,255,0,255, ""),
+ ('hsl-5', 'hsl(120.0, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('hsl-6', 'hsl(+120, +100%, +50%)', 0,255,0,255, ""),
+ ('hsl-clamp-1', 'hsl(120, 200%, 50%)', 0,255,0,255, ""),
+ ('hsl-clamp-2', 'hsl(120, -200%, 49.9%)', 127,127,127,255, ""),
+ ('hsl-clamp-3', 'hsl(120, 100%, 200%)', 255,255,255,255, ""),
+ ('hsl-clamp-4', 'hsl(120, 100%, -200%)', 0,0,0,255, ""),
+ ('hsla-1', 'hsla(120, 100%, 50%, 0.499)', 0,255,0,127, ""),
+ ('hsla-2', 'hsla( 120.0 , 100.0% , 50.0% , 1 )', 0,255,0,255, ""),
+ ('hsla-clamp-1', 'hsla(120, 200%, 50%, 1)', 0,255,0,255, ""),
+ ('hsla-clamp-2', 'hsla(120, -200%, 49.9%, 1)', 127,127,127,255, ""),
+ ('hsla-clamp-3', 'hsla(120, 100%, 200%, 1)', 255,255,255,255, ""),
+ ('hsla-clamp-4', 'hsla(120, 100%, -200%, 1)', 0,0,0,255, ""),
+ ('hsla-clamp-5', 'hsla(120, 100%, 50%, 2)', 0,255,0,255, ""),
+ ('hsla-clamp-6', 'hsla(120, 100%, 0%, -2)', 0,0,0,0, ""),
+ ('svg-1', 'gray', 128,128,128,255, ""),
+ ('svg-2', 'grey', 128,128,128,255, ""),
+ # css-color-4 rgb() color function
+ # https://drafts.csswg.org/css-color/#numeric-rgb
+ ('css-color-4-rgb-1', 'rgb(0, 255.0, 0)', 0,255,0,255, ""),
+ ('css-color-4-rgb-2', 'rgb(0, 255, 0, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgb-3', 'rgb(0, 255, 0, 20%)', 0,255,0,51, ""),
+ ('css-color-4-rgb-4', 'rgb(0 255 0)', 0,255,0,255, ""),
+ ('css-color-4-rgb-5', 'rgb(0 255 0 / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgb-6', 'rgb(0 255 0 / 20%)', 0,255,0,51, ""),
+ ('css-color-4-rgba-1', 'rgba(0, 255.0, 0)', 0,255,0,255, ""),
+ ('css-color-4-rgba-2', 'rgba(0, 255, 0, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgba-3', 'rgba(0, 255, 0, 20%)', 0,255,0,51, ""),
+ ('css-color-4-rgba-4', 'rgba(0 255 0)', 0,255,0,255, ""),
+ ('css-color-4-rgba-5', 'rgba(0 255 0 / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-rgba-6', 'rgba(0 255 0 / 20%)', 0,255,0,51, ""),
+ # css-color-4 hsl() color function
+ # https://drafts.csswg.org/css-color/#the-hsl-notation
+ ('css-color-4-hsl-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsl-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsl-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""),
+ ('css-color-4-hsl-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsl-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsl-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsla-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsla-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""),
+ ('css-color-4-hsla-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""),
+ ('css-color-4-hsla-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""),
+ ('css-color-4-hsla-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""),
+ # currentColor is handled later
+ ]:
+ # TODO: test by retrieving fillStyle, instead of actually drawing?
+ # TODO: test strokeStyle, shadowColor in the same way
+ test = {
+ 'name': '2d.fillStyle.parse.%s' % name,
+ 'notes': notes,
+ 'code': """
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '%s';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == %d,%d,%d,%d;
+ t.done();
+ """ % (string, r,g,b,a),
+ }
+ tests.append(test)
+
+ # Also test that invalid colors are ignored
+ for name, string in [
+ ('hex1', '#f'),
+ ('hex2', '#f0'),
+ ('hex3', '#g00'),
+ ('hex4', '#fg00'),
+ ('hex5', '#ff000'),
+ ('hex6', '#fg0000'),
+ ('hex7', '#ff0000f'),
+ ('hex8', '#fg0000ff'),
+ ('rgb-1', 'rgb(255.0, 0, 0,)'),
+ ('rgb-2', 'rgb(100%, 0, 0)'),
+ ('rgb-3', 'rgb(255, - 1, 0)'),
+ ('rgba-1', 'rgba(100%, 0, 0, 1)'),
+ ('rgba-2', 'rgba(255, 0, 0, 1. 0)'),
+ ('rgba-3', 'rgba(255, 0, 0, 1.)'),
+ ('rgba-4', 'rgba(255, 0, 0, '),
+ ('rgba-5', 'rgba(255, 0, 0, 1,)'),
+ ('hsl-1', 'hsl(0%, 100%, 50%)'),
+ ('hsl-2', 'hsl(z, 100%, 50%)'),
+ ('hsl-3', 'hsl(0, 0, 50%)'),
+ ('hsl-4', 'hsl(0, 100%, 0)'),
+ ('hsl-5', 'hsl(0, 100.%, 50%)'),
+ ('hsl-6', 'hsl(0, 100%, 50%,)'),
+ ('hsla-1', 'hsla(0%, 100%, 50%, 1)'),
+ ('hsla-2', 'hsla(0, 0, 50%, 1)'),
+ ('hsla-3', 'hsla(0, 0, 50%, 1,)'),
+ ('name-1', 'darkbrown'),
+ ('name-2', 'firebrick1'),
+ ('name-3', 'red blue'),
+ ('name-4', '"red"'),
+ ('name-5', '"red'),
+ # css-color-4 color function
+ # comma and comma-less expressions should not mix together.
+ ('css-color-4-rgb-1', 'rgb(255, 0, 0 / 1)'),
+ ('css-color-4-rgb-2', 'rgb(255 0 0, 1)'),
+ ('css-color-4-rgb-3', 'rgb(255, 0 0)'),
+ ('css-color-4-rgba-1', 'rgba(255, 0, 0 / 1)'),
+ ('css-color-4-rgba-2', 'rgba(255 0 0, 1)'),
+ ('css-color-4-rgba-3', 'rgba(255, 0 0)'),
+ ('css-color-4-hsl-1', 'hsl(0, 100%, 50% / 1)'),
+ ('css-color-4-hsl-2', 'hsl(0 100% 50%, 1)'),
+ ('css-color-4-hsl-3', 'hsl(0, 100% 50%)'),
+ ('css-color-4-hsla-1', 'hsla(0, 100%, 50% / 1)'),
+ ('css-color-4-hsla-2', 'hsla(0 100% 50%, 1)'),
+ ('css-color-4-hsla-3', 'hsla(0, 100% 50%)'),
+ # trailing slash
+ ('css-color-4-rgb-4', 'rgb(0 0 0 /)'),
+ ('css-color-4-rgb-5', 'rgb(0, 0, 0 /)'),
+ ('css-color-4-hsl-4', 'hsl(0 100% 50% /)'),
+ ('css-color-4-hsl-5', 'hsl(0, 100%, 50% /)'),
+ ]:
+ test = {
+ 'name': '2d.fillStyle.parse.invalid.%s' % name,
+ 'code': """
+ ctx.fillStyle = '#0f0';
+ try { ctx.fillStyle = '%s'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ t.done();
+ """ % string,
+ }
+ tests.append(test)
+
+ # Some can't have positive tests, only negative tests, because we don't know what color they're meant to be
+ for name, string in [
+ ('system', 'ThreeDDarkShadow'),
+ #('flavor', 'flavor'), # removed from latest CSS3 Color drafts
+ ]:
+ test = {
+ 'name': '2d.fillStyle.parse.%s' % name,
+ 'code': """
+ ctx.fillStyle = '#f00';
+ ctx.fillStyle = '%s';
+ @assert ctx.fillStyle =~ /^#(?!(FF0000|ff0000|f00)$)/; // test that it's not red
+ t.done();
+ """ % (string,),
+ }
+ tests.append(test)
+
+- meta: |
+ cases = [
+ ("zero", "0", 0),
+ ("empty", "", 0),
+ ("onlyspace", " ", 0),
+ ("space", " 100", 100),
+ ("whitespace", "\t\f100", 100),
+ ("plus", "+100", 100),
+ ("minus", "-100", "exception"),
+ ("octal", "0100", 100),
+ ("hex", "0x100", 0x100),
+ ("exp", "100e1", 100e1),
+ ("decimal", "100.999", 100),
+ ("percent", "100%", "exception"),
+ ("em", "100em", "exception"),
+ ("junk", "#!?", "exception"),
+ ("trailingjunk", "100#!?", "exception"),
+ ]
+ def gen(name, string, exp, code):
+ if exp is None:
+ code += "canvas.width = '%s';\ncanvas.height = '%s';\n" % (string, string)
+ code += "@assert canvas.width === 100;\n@assert canvas.height === 50;\n"
+ expected = None
+ elif exp == "exception":
+ code += "@assert throws TypeError canvas.width = '%s';\n" % string
+ expected = None
+ else:
+ code += "canvas.width = '%s';\ncanvas.height = '%s';\n" % (string, string)
+ code += "@assert canvas.width === %s;\n@assert canvas.height === %s;\n" % (exp, exp)
+ expected = None
+
+ code += "t.done();\n"
+
+ if exp == 0:
+ expected = None # can't generate zero-sized PNGs for the expected image
+
+ return code, expected
+
+ for name, string, exp in cases:
+ code = ""
+ code, expected = gen(name, string, exp, code)
+ tests.append( {
+ "name": "2d.canvas.host.size.attributes.parse.%s" % name,
+ "desc": "Parsing of non-negative integers",
+ "code": code,
+ } )
diff --git a/testing/web-platform/tests/html/canvas/tools/yaml/offscreen/the-offscreen-canvas.yaml b/testing/web-platform/tests/html/canvas/tools/yaml/offscreen/the-offscreen-canvas.yaml
new file mode 100644
index 0000000000..ccabe094b8
--- /dev/null
+++ b/testing/web-platform/tests/html/canvas/tools/yaml/offscreen/the-offscreen-canvas.yaml
@@ -0,0 +1,269 @@
+- name: 2d.canvas.host.reference
+ desc: canvas refers back to its canvas
+ code: |
+ @assert ctx.canvas === canvas;
+ t.done();
+
+- name: 2d.canvas.host.readonly
+ desc: canvas is readonly
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ var d = ctx.canvas;
+ @assert offscreenCanvas2 !== d;
+ ctx.canvas = offscreenCanvas2;
+ @assert ctx.canvas === d;
+ t.done();
+
+- name: 2d.canvas.context.exists
+ desc: The 2D context is implemented
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert offscreenCanvas2.getContext('2d') !== null;
+ t.done();
+
+- name: 2d.canvas.context.extraargs.create
+ desc: The 2D context doesn't throw with extra getContext arguments (new context)
+ code: |
+ @assert (new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, "2") !== null;
+ @assert (new OffscreenCanvas(100, 50)).getContext('2d', 123) !== null;
+ @assert (new OffscreenCanvas(100, 50)).getContext('2d', "test") !== null;
+ @assert (new OffscreenCanvas(100, 50)).getContext('2d', undefined) !== null;
+ @assert (new OffscreenCanvas(100, 50)).getContext('2d', null) !== null;
+ @assert (new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance) !== null;
+ t.done();
+
+- name: 2d.canvas.context.extraargs.cache
+ desc: The 2D context doesn't throw with extra getContext arguments (cached)
+ code: |
+ @assert canvas.getContext('2d', false, {}, [], 1, "2") !== null;
+ @assert canvas.getContext('2d', 123) !== null;
+ @assert canvas.getContext('2d', "test") !== null;
+ @assert canvas.getContext('2d', undefined) !== null;
+ @assert canvas.getContext('2d', null) !== null;
+ @assert canvas.getContext('2d', Symbol.hasInstance) !== null;
+ t.done();
+
+- name: 2d.canvas.context.unique
+ desc: getContext('2d') returns the same object
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert offscreenCanvas2.getContext('2d') === offscreenCanvas2.getContext('2d');
+ t.done();
+
+- name: 2d.canvas.context.shared
+ desc: getContext('2d') returns objects which share canvas state
+ code: |
+ var ctx2 = canvas.getContext('2d');
+ ctx.fillStyle = '#f00';
+ ctx2.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ t.done();
+
+- name: 2d.canvas.context.emptystring
+ desc: getContext with empty string returns null
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert throws TypeError offscreenCanvas2.getContext("");
+ t.done();
+
+- name: 2d.canvas.context.unrecognised.badname
+ desc: getContext with unrecognised context name returns null
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert throws TypeError offscreenCanvas2.getContext('This is not an implemented context in any real browser');
+ t.done();
+
+- name: 2d.canvas.context.unrecognised.badsuffix
+ desc: Context name "2d" plus a suffix is unrecognised
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert throws TypeError offscreenCanvas2.getContext("2d#");
+ t.done();
+
+- name: 2d.canvas.context.unrecognised.nullsuffix
+ desc: Context name "2d" plus a "\0" suffix is unrecognised
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert throws TypeError offscreenCanvas2.getContext("2d\0");
+ t.done();
+
+- name: 2d.canvas.context.unrecognised.unicode
+ desc: Context name which kind of looks like "2d" is unrecognised
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert throws TypeError offscreenCanvas2.getContext("2\uFF44");
+ t.done();
+
+- name: 2d.canvas.context.casesensitive
+ desc: Context name "2D" is unrecognised; matching is case sensitive
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert throws TypeError offscreenCanvas2.getContext('2D');
+ t.done();
+
+- name: 2d.canvas.context.arguments.missing
+ code: |
+ var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+ @assert throws TypeError offscreenCanvas2.getContext(); @moz-todo
+ t.done();
+
+
+- name: 2d.canvas.host.initial.color
+ desc: Initial state is transparent black
+ code: |
+ @assert pixel 20,20 == 0,0,0,0;
+ t.done();
+
+- name: 2d.canvas.host.initial.reset.different
+ desc: Changing size resets canvas to transparent black
+ code: |
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ @assert pixel 20,20 == 255,0,0,255;
+ canvas.width = 50;
+ @assert pixel 20,20 == 0,0,0,0;
+ t.done();
+
+- name: 2d.canvas.host.initial.reset.same
+ desc: Setting size (not changing the value) resets canvas to transparent black
+ code: |
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ @assert pixel 20,20 == 255,0,0,255;
+ canvas.width = 100;
+ @assert pixel 20,20 == 0,0,0,0;
+ t.done();
+
+- name: 2d.canvas.host.initial.reset.path
+ desc: Resetting the canvas state resets the current path
+ code: |
+ canvas.width = 100;
+ ctx.rect(0, 0, 100, 50);
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ @assert pixel 20,20 == 0,0,0,0;
+ t.done();
+
+- name: 2d.canvas.host.initial.reset.clip
+ desc: Resetting the canvas state resets the current clip region
+ code: |
+ canvas.width = 100;
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ canvas.width = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 20,20 == 0,255,0,255;
+ t.done();
+
+- name: 2d.canvas.host.initial.reset.transform
+ desc: Resetting the canvas state resets the current transformation matrix
+ code: |
+ canvas.width = 100;
+ ctx.scale(0.1, 0.1);
+ canvas.width = 100;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 20,20 == 0,255,0,255;
+ t.done();
+
+- name: 2d.canvas.host.initial.reset.gradient
+ desc: Resetting the canvas state does not invalidate any existing gradients
+ code: |
+ canvas.width = 50;
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ t.done();
+
+- name: 2d.canvas.host.initial.reset.pattern
+ desc: Resetting the canvas state does not invalidate any existing patterns
+ code: |
+ canvas.width = 30;
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 30, 50);
+ var p = ctx.createPattern(canvas, 'repeat-x');
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = p;
+ ctx.fillRect(0, 0, 100, 50);
+ @assert pixel 50,25 == 0,255,0,255;
+ t.done();
+
+- name: 2d.canvas.host.size.attributes.idl.set.zero
+ desc: Setting width/height IDL attributes to 0
+ code: |
+ canvas.width = 0;
+ canvas.height = 0;
+ @assert canvas.width === 0;
+ @assert canvas.height === 0;
+ t.done();
+
+- name: 2d.canvas.host.size.attributes.idl
+ desc: Getting/setting width/height IDL attributes
+ webidl:
+ - es-unsigned-long
+ code: |
+ canvas.width = "100";
+ canvas.height = "100";
+ @assert canvas.width === 100;
+ @assert canvas.height === 100;
+ canvas.width = "+1.5e2";
+ canvas.height = "0x96";
+ @assert canvas.width === 150;
+ @assert canvas.height === 150;
+ canvas.width = 301.999;
+ canvas.height = 301.001;
+ @assert canvas.width === 301;
+ @assert canvas.height === 301;
+ @assert throws TypeError canvas.width = "400x";
+ @assert throws TypeError canvas.height = "foo";
+ @assert canvas.width === 301;
+ @assert canvas.height === 301;
+ t.done();
+
+- name: 2d.canvas.host.size.attributes.default
+ desc: Default width/height when attributes are missing
+ code: |
+ @assert canvas.width === 100;
+ @assert canvas.height === 50;
+ t.done();
+
+- name: 2d.canvas.host.size.attributes.reflect.setidl
+ desc: Setting IDL attributes updates IDL and content attributes
+ code: |
+ canvas.width = 120;
+ canvas.height = 60;
+ @assert canvas.width === 120;
+ @assert canvas.height === 60;
+ t.done();
+
+- name: 2d.canvas.host.size.attributes.reflect.setidlzero
+ desc: Setting IDL attributes to 0 updates IDL and content attributes
+ code: |
+ canvas.width = 0;
+ canvas.height = 0;
+ @assert canvas.width === 0;
+ @assert canvas.height === 0;
+ t.done();
+
+- name: 2d.canvas.host.size.large
+ notes: Not sure how reasonable this is, but the spec doesn't say there's an upper
+ limit on the size.
+ code: |
+ var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
+ canvas.width = n;
+ canvas.height = n;
+ @assert canvas.width === n;
+ @assert canvas.height === n;
+ t.done();