- name: 2d.getcontext.exists
desc: The 2D context is implemented
testing:
- context.2d
code: |
@assert canvas.getContext('2d') !== null;
- name: 2d.type.name
desc: The 2D context has the correct interface name
testing:
- context.2d.type
code: |
@assert Object.prototype.toString.call(ctx) === '[object CanvasRenderingContext2D]';
- name: 2d.type.exists
desc: The 2D context interface is a property of 'window'
notes: &bindings Defined in "Language Bindings for DOM Specifications" (draft)
testing:
- context.2d.type
code: |
@assert window.CanvasRenderingContext2D;
- name: 2d.type.delete
desc: window.CanvasRenderingContext2D is DontDelete
notes: *bindings
testing:
- context.2d.type
code: |
delete window.CanvasRenderingContext2D;
@assert window.CanvasRenderingContext2D !== undefined;
- name: 2d.type.prototype
desc: window.CanvasRenderingContext2D.prototype is { DontDelete, ReadOnly }, and its methods are not
notes: *bindings
testing:
- context.2d.type
#mozilla: { bug: TODO }
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; @moz-todo
- name: 2d.type.replace
desc: Interface methods can be overridden
notes: *bindings
testing:
- context.2d.type
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.type.extend
desc: Interface methods can be added
notes: *bindings
testing:
- context.2d.type
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.getcontext.unique
desc: getContext('2d') returns the same object
testing:
- context.2d.unique
code: |
@assert canvas.getContext('2d') === canvas.getContext('2d');
- name: 2d.getcontext.shared
desc: getContext('2d') returns objects which share canvas state
testing:
- context.2d.unique
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.voidreturn
desc: void methods return undefined
images:
- yellow.png
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.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.putImageData) {
@assert ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0) === undefined;
}
@assert ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 0, 0, 0, 0, 0, 0) === undefined;
@assert ctx.drawImage(canvas, 0, 0, 0, 0, 0, 0, 0, 0) === undefined;
@assert ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white') === undefined;
- name: 2d.coordinatespace
desc: Coordinate space goes from top-left to bottom-right
notes: This should not be upside down.
mozilla: { disabled } # since it requires manual verification
testing:
- 2d.coordinatespace
code: |
ctx.fillStyle = '#00f';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#0ff';
ctx.fillRect(0, 0, 50, 25);
@assert pixel 25,12 == 0,255,255,255;
@assert pixel 75,12 == 0,0,255,255;
@assert pixel 25,37 == 0,0,255,255;
@assert pixel 75,37 == 0,0,255,255;
@manual; // because we can't tell that getPixelData isn't using the wrong coordinate space too
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, 25)
cr.fill()
- name: 2d.canvas.reference
desc: CanvasRenderingContext2D.canvas refers back to its canvas
testing:
- 2d.canvas
code: |
@assert ctx.canvas === canvas;
- name: 2d.canvas.readonly
desc: CanvasRenderingContext2D.canvas is readonly
testing:
- 2d.canvas.attribute
code: |
var c = document.createElement('canvas');
var d = ctx.canvas;
@assert c !== d;
try { ctx.canvas = c; } catch (e) {} // not sure whether this should throw or not...
@assert ctx.canvas === d;
- 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,
'testing': [ '2d.state.%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 d instead of against %(value)s
ctx.save();
@assert ctx.%(key)s === old;
ctx.restore();
""" % { 'key':key, 'value':value }
} )
tests.append( {
'name': 'initial.reset.2dstate',
'desc': 'Resetting the canvas state resets 2D state variables',
'testing': [ 'initial.reset' ],
'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),
} )
- name: 2d.state.saverestore.transformation
desc: save()/restore() affects the current transformation matrix
testing:
- 2d.state.transformation
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
testing:
- 2d.state.clip
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
testing:
- 2d.state.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
testing:
- 2d.state.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
testing:
- 2d.state.save
- 2d.state.restore
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
testing:
- 2d.state.save
- 2d.state.restore
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
testing:
- 2d.state.restore.underflow
mozilla: { disabled, bug: 296821 }
code: |
for (var i = 0; i < 16; ++i)
ctx.restore();
ctx.lineWidth = 0.5;
ctx.restore();
@assert ctx.lineWidth == 0.5;
- name: 2d.transformation.order
desc: Transformations are applied in the right order
testing:
- 2d.transformation.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
testing:
- 2d.transformation.scale
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
testing:
- 2d.transformation.scale
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
testing:
- 2d.transformation.scale
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.
testing:
- 2d.transformation.scale
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.infinity
desc: scale() with Infinity makes nothing be drawn
testing:
- 2d.transformation.scale
mozilla: { disabled } # TODO: report bug?
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.save();
ctx.scale(Infinity, 10);
ctx.fillStyle = '#f00';
ctx.fillRect(-10, -10, 20, 20);
ctx.restore();
ctx.save();
ctx.scale(10, Infinity);
ctx.fillStyle = '#f00';
ctx.fillRect(-10, -10, 20, 20);
ctx.restore();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.transformation.scale.neginfinity
desc: scale() with -Infinity makes nothing be drawn
testing:
- 2d.transformation.scale
mozilla: { disabled } # TODO: report bug?
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.save();
ctx.scale(-Infinity, 10);
ctx.fillStyle = '#f00';
ctx.fillRect(-10, -10, 20, 20);
ctx.restore();
ctx.save();
ctx.scale(10, -Infinity);
ctx.fillStyle = '#f00';
ctx.fillRect(-10, -10, 20, 20);
ctx.restore();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.transformation.scale.nan
desc: scale() with NaN throws an exception
testing:
- 2d.transformation.scale
mozilla: { disabled } # TODO: report bug?
code: |
@assert throws NOT_SUPPORTED_ERR ctx.scale(NaN, 1);
@assert throws NOT_SUPPORTED_ERR ctx.scale(1, NaN);
@assert throws NOT_SUPPORTED_ERR ctx.scale(NaN, NaN);
- name: 2d.transformation.scale.multiple
desc: Multiple scale()s combine
testing:
- 2d.transformation.scale.multiple
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
testing:
- 2d.transformation.rotate
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
testing:
- 2d.transformation.rotate.radians
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.rotate(Math.PI);
ctx.fillStyle = '#0f0';
ctx.fillRect(-100, -50, 100, 50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.transformation.rotate.direction
testing:
- 2d.transformation.rotate.direction
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
testing:
- 2d.transformation.rotate
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
testing:
- 2d.transformation.rotate
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.infinity
testing:
- 2d.transformation.rotate
#mozilla: { bug: TODO }
code: |
@assert throws NOT_SUPPORTED_ERR ctx.rotate(Infinity); @moz-todo
- name: 2d.transformation.rotate.neginfinity
testing:
- 2d.transformation.rotate
#mozilla: { bug: TODO }
code: |
@assert throws NOT_SUPPORTED_ERR ctx.rotate(-Infinity); @moz-todo
- name: 2d.transformation.rotate.nan
testing:
- 2d.transformation.rotate
#mozilla: { bug: TODO }
code: |
@assert throws NOT_SUPPORTED_ERR ctx.rotate(NaN); @moz-todo
- name: 2d.transformation.translate.basic
testing:
- 2d.transformation.translate
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.infinity
testing:
- 2d.transformation.translate
mozilla: { disabled } # TODO: report bug?
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.translate(Infinity, 0);
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.transformation.translate.nan
testing:
- 2d.transformation.translate
mozilla: { disabled } # TODO: report bug?
code: |
@assert throws NOT_SUPPORTED_ERR ctx.translate(NaN, 0);
- name: 2d.transformation.transform.identity
testing:
- 2d.transformation.transform
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
testing:
- 2d.transformation.transform
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
testing:
- 2d.transformation.transform.multiply
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.infinity
testing:
- 2d.transformation.transform
mozilla: { disabled } # TODO: report bug?
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.transform(Infinity,0, 0,Infinity, 0,0);
ctx.fillStyle = '#f00';
ctx.fillRect(-10, -10, 20, 20);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.transformation.setTransform.skewed
testing:
- 2d.transformation.setTransform
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
testing:
- 2d.transformation.setTransform.identity
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.setTransform(1/2,0, 0,1/2, 0,0);
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.composite.globalAlpha.range
testing:
- 2d.composite.globalAlpha.range
code: |
ctx.globalAlpha = 0.5;
var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
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
mozilla: { disabled } # TODO: report bug?
testing:
- 2d.composite.globalAlpha.range
code: |
ctx.globalAlpha = 0.5;
var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
@assert throws NOT_SUPPORTED_ERR ctx.globalAlpha = Infinity;
@assert ctx.globalAlpha == a;
@assert throws NOT_SUPPORTED_ERR ctx.globalAlpha = -Infinity;
@assert ctx.globalAlpha == a;
@assert throws NOT_SUPPORTED_ERR ctx.globalAlpha = NaN;
@assert ctx.globalAlpha == a;
- name: 2d.composite.globalAlpha.default
testing:
- 2d.composite.globalAlpha.default
code: |
@assert ctx.globalAlpha === 1.0;
- name: 2d.composite.globalAlpha.fill
testing:
- 2d.composite.globalAlpha.shape
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
@assert pixel 50,25 ==~ 2,253,0,255;
expected: green
- name: 2d.composite.globalAlpha.image
testing:
- 2d.composite.globalAlpha.image
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
ctx.drawImage(document.getElementById('red.png'), 0, 0);
@assert pixel 50,25 ==~ 2,253,0,255;
expected: green
- name: 2d.composite.globalAlpha.canvas
testing:
- 2d.composite.globalAlpha.image
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.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
ctx.drawImage(canvas2, 0, 0);
@assert pixel 50,25 ==~ 2,253,0,255;
expected: green
- name: 2d.composite.globalAlpha.imagepattern
mozilla: { bug: 401790 }
testing:
- 2d.composite.globalAlpha.image
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = ctx.createPattern(document.getElementById('red.png'), 'no-repeat');
ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
ctx.fillRect(0, 0, 100, 50);
@assert pixel 50,25 ==~ 2,253,0,255; @moz-todo
expected: green
- name: 2d.composite.globalAlpha.canvaspattern
mozilla: { bug: 401790 }
testing:
- 2d.composite.globalAlpha.image
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');
ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
ctx.fillRect(0, 0, 100, 50);
@assert pixel 50,25 ==~ 2,253,0,255; @moz-todo
expected: green
- meta: |
# Proposed definition - 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'),
]
# 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((RA, GA, BA, aA), (RB, GB, BB, aB), FA_code, FB_code):
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_css((r,g,b,a)):
return 'rgba(%d,%d,%d,%f)' % (r, g, b, a)
def to_test((r,g,b,a)):
return '%d,%d,%d,%d' % (r, g, b, int(a*255))
def to_cairo((r,g,b,a)):
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),
'notes': 'Assumes this definition.',
'testing': [ '2d.composite.%s' % 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),
'notes': 'Assumes this definition.',
'testing': [ '2d.composite.%s' % 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),
} )
notes = """Pixels not covered by the source object should be drawn as (0,0,0,0), not left unchanged.
Assumes this
definition of the operations."""
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)
expected1 = calc_output(src, dest, FA_code, FB_code)
tests.append( {
'name': '2d.composite.%s.%s' % (name, op),
'notes': notes,
'testing': [ '2d.composite.%s' % op ],
'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)
expected1 = calc_output(src, dest, FA_code, FB_code)
tests.append( {
'name': '2d.composite.%s.%s' % (name, op),
'notes': notes,
'testing': [ '2d.composite.%s' % op ],
'images': [ 'yellow.png' ],
'code': """
ctx.fillStyle = 'rgba%s';
ctx.fillRect(0, 0, 100, 50);
ctx.globalCompositeOperation = '%s';
ctx.drawImage(document.getElementById('yellow.png'), 0, 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 (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)
expected1 = calc_output(src, dest, FA_code, FB_code)
tests.append( {
'name': '2d.composite.%s.%s' % (name, op),
'notes': notes,
'testing': [ '2d.composite.%s' % op ],
'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)),
} )
- name: 2d.composite.operation.get
testing:
- 2d.composite.operation
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
mozilla: { disabled, bug: 401788 }
testing:
- 2d.composite.operation.unrecognised
code: |
ctx.globalCompositeOperation = 'xor';
ctx.globalCompositeOperation = 'nonexistent';
@assert ctx.globalCompositeOperation == 'xor';
- name: 2d.composite.operation.darker
#mozilla: { bug: TODO }
testing:
- 2d.composite.operation.unrecognised
code: |
ctx.globalCompositeOperation = 'xor';
ctx.globalCompositeOperation = 'darker';
@assert ctx.globalCompositeOperation == 'xor'; @moz-todo
- name: 2d.composite.operation.over
#mozilla: { bug: TODO }
testing:
- 2d.composite.operation.unrecognised
code: |
ctx.globalCompositeOperation = 'xor';
ctx.globalCompositeOperation = 'over';
@assert ctx.globalCompositeOperation == 'xor'; @moz-todo
- name: 2d.composite.operation.clear
#mozilla: { bug: TODO }
testing:
- 2d.composite.operation.unrecognised
code: |
ctx.globalCompositeOperation = 'xor';
ctx.globalCompositeOperation = 'clear';
@assert ctx.globalCompositeOperation == 'xor'; @moz-todo
- name: 2d.composite.operation.highlight
mozilla: { disabled, bug: 401788 }
testing:
- 2d.composite.operation.unrecognised
code: |
ctx.globalCompositeOperation = 'xor';
ctx.globalCompositeOperation = 'highlight';
@assert ctx.globalCompositeOperation == 'xor';
- name: 2d.composite.operation.nullsuffix
mozilla: { disabled, bug: 401788 }
testing:
- 2d.composite.operation.exact
code: |
ctx.globalCompositeOperation = 'xor';
ctx.globalCompositeOperation = 'source-over\0';
@assert ctx.globalCompositeOperation == 'xor';
- name: 2d.composite.operation.casesensitive
mozilla: { disabled, bug: 401788 }
testing:
- 2d.composite.operation.casesensitive
code: |
ctx.globalCompositeOperation = 'xor';
ctx.globalCompositeOperation = 'Source-over';
@assert ctx.globalCompositeOperation == 'xor';
- name: 2d.composite.operation.default
testing:
- 2d.composite.operation.default
code: |
@assert ctx.globalCompositeOperation == 'source-over';
- meta: |
# Try most of the CSS3 Color values - http://www.w3.org/TR/css3-color/#colorunits
for name, string, r,g,b,a, notes in [
('html4', 'limE', 0,255,0,255, ""),
('hex3', '#0f0', 0,255,0,255, ""),
('hex6', '#00fF00', 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 colours are clamped to [0,255].'),
('rgb-clamp-2', 'rgb(-200%, 200%, -200%)', 0,255,0,255, 'Assumes colours 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...)'),
('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-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, ""),
('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, ""),
('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, ""),
('svg-1', 'gray', 128,128,128,255, ""),
('svg-2', 'grey', 128,128,128,255, ""),
('current', 'currentColor', 0,255,0,255, ""),
]:
# TODO: test by retrieving fillStyle, instead of actually drawing
test = {
'name': '2d.fillStyle.parse.%s' % name,
'testing': [ '2d.colours.parse' ],
'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.),
}
if name == 'current':
test['canvas'] = 'width="100" height="50" style="color:#0f0"'
test['mozilla'] = { 'disabled': None } # TODO: report bug?
tests.append(test)
# Also test that invalid colours are ignored
for name, string in [
('hex3', '#g00'),
('hex6', '#fg0000'),
('rgb-1', 'rgb(255.0, 0, 0)'),
('rgb-2', 'rgb(255, 0.0, 0)'),
('rgb-3', 'rgb(255.0, 0, 0,)'),
('rgb-4', 'rgb(100%, 0, 0)'),
('rgb-5', 'rgb(255 0 0)'),
('rgb-6', 'rgb(255, - 1, 0)'),
('rgb-7', 'rgb(255, 0, 0, 1)'),
('rgba-1', 'rgba(255, 0, 0)'),
('rgba-2', 'rgba(255.0, 0, 0, 1)'),
('rgba-3', 'rgba(100%, 0, 0, 1)'),
('rgba-4', 'rgba(255, 0, 0, 100%)'),
('rgba-5', 'rgba(255, 0, 0, 1. 0)'),
('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%, 100%, 1)'),
('hsla-1', 'hsla(0%, 100%, 50%, 1)'),
('hsla-2', 'hsla(0, 0, 50%, 1)'),
]:
test = {
'name': '2d.fillStyle.parse.invalid.%s' % name,
'testing': [ '2d.colours.parse' ],
'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 colour they're meant to be
for name, string in [
('system', 'ThreeDDarkShadow'),
('flavor', 'flavor'),
]:
test = {
'name': '2d.fillStyle.parse.%s' % name,
'testing': [ '2d.colours.parse' ],
'code': """
ctx.fillStyle = '#f00';
ctx.fillStyle = '%s';
@assert ctx.fillStyle =~ /^#(?!(FF0000|ff0000|f00)$)/; // test that it's not red
""" % (string,),
}
tests.append(test)
- name: 2d.fillStyle.invalidstring
testing:
- 2d.colours.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
testing:
- 2d.colours.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
testing:
- 2d.colours.getcolour.solid
code: |
ctx.fillStyle = '#fa0';
@assert ctx.fillStyle === '#ffaa00';
- name: 2d.fillStyle.get.semitransparent
testing:
- 2d.colours.getcolour.transparent
code: |
ctx.fillStyle = 'rgba(255,255,255,0.45)';
@assert ctx.fillStyle =~ /^rgba\(255, 255, 255, 0\.4\d+\)$/;
- name: 2d.fillStyle.get.transparent
testing:
- 2d.colours.getcolour.transparent
code: |
ctx.fillStyle = 'rgba(0,0,0,0)';
@assert ctx.fillStyle == 'rgba(0, 0, 0, 0.0)';
- name: 2d.fillStyle.default
testing:
- 2d.colours.default
code: |
@assert ctx.fillStyle == '#000000';
- name: 2d.strokeStyle.default
testing:
- 2d.colours.default
code: |
@assert ctx.strokeStyle == '#000000';
- name: 2d.gradient.object.return
testing:
- 2d.gradient.return.linear
- 2d.gradient.return.radial
code: |
var g1 = ctx.createLinearGradient(0, 0, 100, 0);
@assert Object.prototype.toString.call(g1) === '[object CanvasGradient]';
@assert g1.addColorStop !== undefined;
var g2 = ctx.createRadialGradient(0, 0, 10, 0, 0, 20);
@assert Object.prototype.toString.call(g2) === '[object CanvasGradient]';
@assert g2.addColorStop !== undefined;
- name: 2d.gradient.interpolate.solid
testing:
- 2d.gradient.interpolate.linear
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.colour
testing:
- 2d.gradient.interpolate.linear
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;
@assert pixel 50,25 ==~ 127,127,127,255;
@assert pixel 75,25 ==~ 63,63,191,255;
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
testing:
- 2d.gradient.interpolate.linear
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;
@assert pixel 50,25 ==~ 127,127,127,255;
@assert pixel 75,25 ==~ 63,63,191,255;
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.colouralpha
testing:
- 2d.gradient.interpolate.alpha
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 ==~ 191,191,63,63;
@assert pixel 50,25 ==~ 127,127,127,127;
@assert pixel 75,25 ==~ 63,63,191,191;
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
testing:
- 2d.gradient.outside.first
- 2d.gradient.outside.last
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
testing:
- 2d.gradient.zerosize
#mozilla: { bug: TODO }
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.vertical
testing:
- 2d.gradient.interpolate.linear
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
testing:
- 2d.gradient.interpolate.linear
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;
@assert pixel 100,25 ==~ 0,255,255,255;
@assert pixel 150,25 ==~ 127,127,255,255;
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
testing:
- 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
testing:
- 2d.gradient.interpolate.overlap
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
testing:
- 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
testing:
- 2d.gradient.update
code: |
var g = ctx.createLinearGradient(-100, 0, 200, 0);
g.addColorStop(0, '#f00');
g.addColorStop(1, '#f00');
ctx.fillStyle = g;
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
testing:
- 2d.gradient.object
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 = 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);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- name: 2d.gradient.object.invalidoffset
testing:
- 2d.gradient.invalidoffset
#mozilla: { bug: TODO }
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 NOT_SUPPORTED_ERR g.addColorStop(Infinity, '#000'); @moz-todo
@assert throws NOT_SUPPORTED_ERR g.addColorStop(-Infinity, '#000'); @moz-todo
@assert throws NOT_SUPPORTED_ERR g.addColorStop(NaN, '#000'); @moz-todo
- name: 2d.gradient.object.invalidcolour
testing:
- 2d.gradient.invalidcolour
code: |
var g = ctx.createLinearGradient(0, 0, 100, 0);
@assert throws SYNTAX_ERR g.addColorStop(0, "");
@assert throws SYNTAX_ERR g.addColorStop(0, 'undefined');
- name: 2d.gradient.radial.negative
testing:
- 2d.gradient.radial.negative
#mozilla: { bug: TODO }
code: |
@assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); @moz-todo
- name: 2d.gradient.radial.invalid
#mozilla: { bug: TODO }
code: |
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.createRadialGradient(0, 0, NaN, 0, 0, 1); @moz-todo
- name: 2d.gradient.radial.inside1
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.inside2
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.inside3
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.outside1
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.outside2
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.outside3
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.touch1
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.touch2
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.touch3
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.equal
testing:
- 2d.gradient.radial.equal
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.cone.behind
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.cone.front
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.cone.bottom
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.cone.top
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.cone.beside
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.gradient.radial.cone.cylinder
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.cone.shape1
testing:
- 2d.gradient.radial.rendering
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;
@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.gradient.radial.cone.shape2
testing:
- 2d.gradient.radial.rendering
mozilla: { disabled } # TODO: report bug?
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;
@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.pattern.basic.type
testing:
- 2d.pattern.return
images:
- green.png
code: |
var img = document.getElementById('green.png');
var pattern = ctx.createPattern(img, 'no-repeat');
@assert Object.prototype.toString.call(pattern) === '[object CanvasPattern]';
- name: 2d.pattern.basic.image
testing:
- 2d.pattern.painting
images:
- green.png
code: |
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);
@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.pattern.basic.canvas
testing:
- 2d.pattern.painting
code: |
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);
@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.pattern.basic.zerocanvas
notes: The behaviour here is unspecified - I'll assume it's not meant to draw anything.
mozilla: { disabled } # unspecified
code: |
var canvas2 = document.createElement('canvas');
canvas2.width = 0;
canvas2.height = 0;
@assert canvas2.width === 0;
@assert canvas2.height === 0;
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = '#f00';
ctx2.fillRect(0, 0, 100, 50);
var pattern = ctx.createPattern(canvas2, '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
- name: 2d.pattern.basic.nocontext
testing:
- 2d.pattern.painting
code: |
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 = 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
- name: 2d.pattern.image.undefined
testing:
- 2d.pattern.wrongtype
#mozilla: { bug: TODO }
code: |
@assert throws TYPE_MISMATCH_ERR ctx.createPattern(undefined, 'repeat'); @moz-todo
- name: 2d.pattern.image.null
testing:
- 2d.pattern.wrongtype
#mozilla: { bug: TODO }
code: |
@assert throws TYPE_MISMATCH_ERR ctx.createPattern(null, 'repeat'); @moz-todo
- name: 2d.pattern.image.string
testing:
- 2d.pattern.wrongtype
#mozilla: { bug: TODO }
code: |
@assert throws TYPE_MISMATCH_ERR ctx.createPattern('../images/green.png', 'repeat'); @moz-todo
- name: 2d.pattern.image.incomplete
testing:
- 2d.pattern.incomplete
#mozilla: { bug: TODO }
code: |
var img = new Image();
@assert img.complete === false; @moz-todo
@assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat'); @moz-todo
- name: 2d.pattern.image.incomplete2
DISABLED: Depends on unspecified 'complete' behaviour
testing:
- 2d.pattern.incomplete
code: |
var img = new Image();
img.src = 'http://www.google.com/images/logo.gif';
@assert img.complete === false; // FIXME: it is not (yet) specified whether cached image loads can set 'complete' immediately
@assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
img.src = "";
- name: 2d.pattern.image.incomplete3
DISABLED: Depends on unspecified 'complete' behaviour
testing:
- 2d.pattern.incomplete
images:
- green.png
code: |
var img = document.getElementById('green.png');
img.src = "";
@assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
- name: 2d.pattern.image.incomplete4
DISABLED: Depends on unspecified 'complete' behaviour
testing:
- 2d.pattern.incomplete
images:
- green.png
code: |
var img = document.getElementById('green.png');
img.src = '../images/red.png';
@assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat');
- name: 2d.pattern.image.broken
testing:
- 2d.pattern.incomplete
#mozilla: { bug: TODO }
images:
- broken.png
code: |
var img = document.getElementById('broken.png');
@assert img.complete === false; @moz-todo
@assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat'); @moz-todo
- name: 2d.pattern.repeat.empty
testing:
- 2d.pattern.missing
images:
- green-1x1.png
code: |
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);
@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.pattern.repeat.null
testing:
- 2d.pattern.missing
images:
- green-1x1.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
var img = document.getElementById('green-1x1.png');
var pattern = ctx.createPattern(img, null);
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
- name: 2d.pattern.repeat.undefined
testing:
- 2d.pattern.unrecognised
code: |
@assert throws SYNTAX_ERR ctx.createPattern(canvas, undefined);
- name: 2d.pattern.repeat.missing
#mozilla: { bug: TODO }
testing:
- 2d.pattern.unrecognised
code: |
@assert throws SYNTAX_ERR ctx.createPattern(canvas); @moz-todo
- name: 2d.pattern.repeat.unrecognised
testing:
- 2d.pattern.unrecognised
code: |
@assert throws SYNTAX_ERR ctx.createPattern(canvas, "invalid");
- name: 2d.pattern.repeat.case
testing:
- 2d.pattern.exact
code: |
@assert throws SYNTAX_ERR ctx.createPattern(canvas, "Repeat");
- name: 2d.pattern.repeat.nullsuffix
testing:
- 2d.pattern.exact
code: |
@assert throws SYNTAX_ERR ctx.createPattern(canvas, "repeat\0");
- name: 2d.pattern.modify.image1
testing:
- 2d.pattern.modify
images:
- green.png
code: |
var img = document.getElementById('green.png');
var pattern = ctx.createPattern(img, 'no-repeat');
deferTest();
img.onload = wrapFunction(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
testing:
- 2d.pattern.modify
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 = wrapFunction(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
testing:
- 2d.pattern.modify
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);
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
- name: 2d.pattern.modify.canvas2
testing:
- 2d.pattern.modify
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);
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
- name: 2d.pattern.crosscanvas
code: |
images:
- green.png
code: |
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);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.pattern.paint.norepeat.basic
testing:
- 2d.pattern.painting
images:
- green.png
code: |
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);
@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.pattern.paint.norepeat.outside
testing:
- 2d.pattern.painting
images:
- red.png
code: |
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);
@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.pattern.paint.norepeat.coord1
testing:
- 2d.pattern.painting
images:
- green.png
code: |
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);
@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.pattern.paint.norepeat.coord2
testing:
- 2d.pattern.painting
images:
- green.png
code: |
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);
@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.pattern.paint.coord3
testing:
- 2d.pattern.painting
images:
- red.png
code: |
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);
@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.pattern.paint.repeat.basic
testing:
- 2d.pattern.painting
images:
- green-16x16.png
code: |
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);
@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.pattern.paint.repeat.outside
testing:
- 2d.pattern.painting
images:
- green-16x16.png
code: |
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);
@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.pattern.paint.repeat.coord1
testing:
- 2d.pattern.painting
images:
- rgrg-256x256.png
code: |
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);
@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.pattern.paint.repeat.coord2
testing:
- 2d.pattern.painting
images:
- ggrr-256x256.png
code: |
var img = document.getElementById('ggrr-256x256.png');
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
- name: 2d.pattern.paint.repeat.coord3
testing:
- 2d.pattern.painting
#mozilla: { bug: TODO }
images:
- rgrg-256x256.png
code: |
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);
@assert pixel 1,1 == 0,255,0,255; @moz-todo
@assert pixel 98,1 == 0,255,0,255; @moz-todo
@assert pixel 1,48 == 0,255,0,255; @moz-todo
@assert pixel 98,48 == 0,255,0,255; @moz-todo
expected: green
- name: 2d.pattern.paint.repeatx.basic
testing:
- 2d.pattern.painting
images:
- green-16x16.png
code: |
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);
@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.pattern.paint.repeatx.outside
testing:
- 2d.pattern.painting
#mozilla: { bug: TODO }
images:
- red-16x16.png
code: |
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);
@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; @moz-todo
expected: green
- name: 2d.pattern.paint.repeatx.coord1
testing:
- 2d.pattern.painting
#mozilla: { bug: TODO }
images:
- red-16x16.png
code: |
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);
@assert pixel 1,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;
@assert pixel 98,25 == 0,255,0,255;
@assert pixel 1,48 == 0,255,0,255; @moz-todo
@assert pixel 98,48 == 0,255,0,255; @moz-todo
expected: green
- name: 2d.pattern.paint.repeaty.basic
testing:
- 2d.pattern.painting
images:
- green-16x16.png
code: |
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);
@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.pattern.paint.repeaty.outside
testing:
- 2d.pattern.painting
#mozilla: { bug: TODO }
images:
- red-16x16.png
code: |
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);
@assert pixel 1,1 == 0,255,0,255;
@assert pixel 98,1 == 0,255,0,255; @moz-todo
@assert pixel 1,48 == 0,255,0,255;
@assert pixel 98,48 == 0,255,0,255; @moz-todo
expected: green
- name: 2d.pattern.paint.repeaty.coord1
testing:
- 2d.pattern.painting
#mozilla: { bug: TODO }
images:
- red-16x16.png
code: |
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);
@assert pixel 1,1 == 0,255,0,255; @moz-todo
@assert pixel 50,1 == 0,255,0,255;
@assert pixel 98,1 == 0,255,0,255; @moz-todo
@assert pixel 1,48 == 0,255,0,255; @moz-todo
@assert pixel 50,48 == 0,255,0,255;
@assert pixel 98,48 == 0,255,0,255; @moz-todo
expected: green
- name: 2d.line.defaults
testing:
- 2d.lineWidth.default
- 2d.lineCap.default
- 2d.lineJoin.default
- 2d.miterLimit.default
code: |
@assert ctx.lineWidth === 1;
@assert ctx.lineCap === 'butt';
@assert ctx.lineJoin === 'miter';
@assert ctx.miterLimit === 10;
expected: none
- name: 2d.line.invalid.lineWidth
testing:
- 2d.lineWidth.invalid
#mozilla: { bug: TODO }
code: |
ctx.lineWidth = 1.5;
@assert ctx.lineWidth === 1.5;
ctx.lineWidth = 1.5;
ctx.lineWidth = 0;
@assert ctx.lineWidth === 1.5; @moz-todo
ctx.lineWidth = 1.5;
ctx.lineWidth = -1;
@assert ctx.lineWidth === 1.5; @moz-todo
ctx.lineWidth = 1.5;
@assert throws NOT_SUPPORTED_ERR ctx.lineWidth = Infinity; @moz-todo
@assert ctx.lineWidth === 1.5;
ctx.lineWidth = 1.5;
@assert throws NOT_SUPPORTED_ERR ctx.lineWidth = -Infinity; @moz-todo
@assert ctx.lineWidth === 1.5;
ctx.lineWidth = 1.5;
@assert throws NOT_SUPPORTED_ERR ctx.lineWidth = NaN; @moz-todo
@assert ctx.lineWidth === 1.5;
expected: none
- name: 2d.line.invalid.lineCap
testing:
- 2d.lineCap.invalid
mozilla: { disabled, bug: 401788 }
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';
expected: none
- name: 2d.line.invalid.lineJoin
mozilla: { disabled, bug: 401788 }
testing:
- 2d.lineJoin.invalid
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';
expected: none
- name: 2d.line.invalid.miterLimit
testing:
- 2d.miterLimit.invalid
#mozilla: { bug: TODO }
code: |
ctx.miterLimit = 1.5;
@assert ctx.miterLimit === 1.5;
ctx.miterLimit = 1.5;
ctx.miterLimit = 0;
@assert ctx.miterLimit === 1.5; @moz-todo
ctx.miterLimit = 1.5;
ctx.miterLimit = -1;
@assert ctx.miterLimit === 1.5; @moz-todo
ctx.miterLimit = 1.5;
@assert throws NOT_SUPPORTED_ERR ctx.miterLimit = Infinity; @moz-todo
@assert ctx.miterLimit === 1.5;
ctx.miterLimit = 1.5;
@assert throws NOT_SUPPORTED_ERR ctx.miterLimit = -Infinity; @moz-todo
@assert ctx.miterLimit === 1.5;
ctx.miterLimit = 1.5;
@assert throws NOT_SUPPORTED_ERR ctx.miterLimit = NaN; @moz-todo
@assert ctx.miterLimit === 1.5;
expected: none
- name: 2d.line.lineWidth.basic
testing:
- 2d.lineWidth
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.lineWidth.transformed
testing:
- 2d.lineWidth
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.lineCap.butt
testing:
- 2d.lineCap.butt
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.lineCap.round
testing:
- 2d.lineCap.round
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.lineCap.square
testing:
- 2d.lineCap.square
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.lineJoin.bevel
testing:
- 2d.lineJoin.bevel
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.lineJoin.round
testing:
- 2d.lineJoin.round
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.lineJoin.miter
testing:
- 2d.lineJoin.miter
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
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
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.zeroline.corner
code: |
ctx.fillStyle = '#f00';
ctx.strokeStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.lineJoin = 'miter';
ctx.lineWidth = 200;
ctx.beginPath();
ctx.moveTo(1000, 50);
ctx.lineTo(100, 50);
ctx.lineTo(100, 50);
ctx.lineTo(100, 50);
ctx.lineTo(100, 1000);
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.zeroline.join
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.strokeStyle = '#f00';
ctx.lineWidth = 150;
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.lineTo(50, 25);
ctx.lineTo(50, 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.parallel
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.cap.open
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
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.zeroline.round
#mozilla: { bug: TODO }
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.strokeStyle = '#f00';
ctx.lineWidth = 150;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.lineTo(50, 25);
ctx.stroke();
@assert pixel 1,1 == 0,255,0,255; @moz-todo
@assert pixel 48,1 == 0,255,0,255; @moz-todo
@assert pixel 48,48 == 0,255,0,255; @moz-todo
@assert pixel 1,48 == 0,255,0,255; @moz-todo
expected: green
- name: 2d.line.cap.zeroline.square
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.strokeStyle = '#f00';
ctx.lineWidth = 100;
ctx.lineCap = 'square';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.lineTo(50, 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.cap.zerobezier.round
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.strokeStyle = '#f00';
ctx.lineWidth = 150;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(50, 25);
ctx.bezierCurveTo(50, 25, 50, 25, 50, 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.miter.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);
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
mozilla: { bug: 401791 }
code: |
// In FF3, this works if you do something like ctx.rotate(0.001);
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; @moz-todo
@assert pixel 48,1 == 0,255,0,255; @moz-todo
@assert pixel 48,48 == 0,255,0,255; @moz-todo
@assert pixel 1,48 == 0,255,0,255; @moz-todo
expected: green
- name: 2d.line.miter.lineedge
mozilla: { bug: 401791 }
code: |
// In Safari/FF3, this works if you do something like ctx.rotate(0.001);
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; @moz-todo
@assert pixel 48,1 == 0,255,0,255; @moz-todo
@assert pixel 48,48 == 0,255,0,255; @moz-todo
@assert pixel 1,48 == 0,255,0,255; @moz-todo
expected: green
- name: 2d.line.miter.within
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.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.clearRect.negative
mozilla: { disabled } # TODO: report bug?
testing:
- 2d.rect.negative
code: |
@assert throws INDEX_SIZE_ERR ctx.clearRect(0, 0, -1, 1);
@assert throws INDEX_SIZE_ERR ctx.clearRect(0, 0, 1, -1);
- name: 2d.clearRect.basic
testing:
- 2d.clearRect
background: "#0f0"
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: green
- name: 2d.clearRect.path
testing:
- 2d.clearRect
background: "#f00"
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
testing:
- 2d.clearRect
background: "#f00"
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.transform
testing:
- 2d.clearRect
background: "#0f0"
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: green
- name: 2d.clearRect.globalalpha
testing:
- 2d.clearRect
background: "#0f0"
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: green
- name: 2d.clearRect.globalcomposite
testing:
- 2d.clearRect
background: "#0f0"
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: green
- name: 2d.clearRect.clip
testing:
- 2d.clearRect
background: "#f00"
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
testing:
- 2d.clearRect
background: "#f00"
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.fillRect.negative
testing:
- 2d.rect.negative
#mozilla: { bug: TODO }
code: |
@assert throws INDEX_SIZE_ERR ctx.fillRect(0, 0, -1, 1); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.fillRect(0, 0, 1, -1); @moz-todo
- name: 2d.fillRect.basic
testing:
- 2d.fillRect
background: "#f00"
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.fillRect.path
testing:
- 2d.fillRect
background: "#f00"
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
testing:
- 2d.fillRect
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.fillRect.transform
testing:
- 2d.fillRect
background: "#f00"
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
testing:
- 2d.fillRect
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
testing:
- 2d.fillRect
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#f00';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 50;
// Shadows are optional, so just test that if they apply to fill() then they apply to fillRect() too
ctx.beginPath();
ctx.rect(0, -50, 100, 50);
ctx.shadowColor = '#f00';
ctx.fill();
ctx.shadowColor = '#0f0';
ctx.fillRect(0, -50, 100, 50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.strokeRect.negative
testing:
- 2d.rect.negative
#mozilla: { bug: TODO }
code: |
@assert throws INDEX_SIZE_ERR ctx.strokeRect(0, 0, -1, 1); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.strokeRect(0, 0, 1, -1); @moz-todo
- name: 2d.strokeRect.basic
testing:
- 2d.strokeRect
background: "#f00"
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
testing:
- 2d.strokeRect
background: "#f00"
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
testing:
- 2d.strokeRect
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 250;
ctx.strokeRect(50, 25, 0, 0);
@assert pixel 50,25 == 0,0,0,0;
expected: green
- name: 2d.strokeRect.zero.2
testing:
- 2d.strokeRect
#mozilla: { bug: TODO }
background: "#0f0"
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; @moz-todo
expected: green
- name: 2d.strokeRect.zero.3
testing:
- 2d.strokeRect
background: "#f00"
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
testing:
- 2d.strokeRect
background: "#0f0"
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: green
- name: 2d.strokeRect.zero.5
notes: This doesn't really follow the spec - it's assuming the line is closed. See message.
testing:
- 2d.strokeRect
background: "#f00"
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.transform
testing:
- 2d.strokeRect
background: "#f00"
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
testing:
- 2d.strokeRect
background: "#0f0"
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: green
- name: 2d.strokeRect.globalcomposite
testing:
- 2d.strokeRect
background: "#0f0"
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: green
- name: 2d.strokeRect.clip
testing:
- 2d.strokeRect
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
testing:
- 2d.strokeRect
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#f00';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 50;
// Shadows are optional, so just test that if they apply to fill() then they apply to strokeRect() too
ctx.beginPath();
ctx.rect(0, -50, 100, 50);
ctx.shadowColor = '#f00';
ctx.fill();
ctx.shadowColor = '#0f0';
ctx.strokeStyle = '#f00';
ctx.lineWidth = 50;
ctx.strokeRect(0, -75, 100, 50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.path.initial
testing:
- 2d.path.initial
#mozilla: { bug: TODO }
background: "#0f0"
code: |
ctx.lineTo(0, 0);
ctx.lineTo(100, 0);
ctx.lineTo(100, 50);
ctx.lineTo(0, 50);
ctx.closePath();
ctx.fillStyle = '#f00';
ctx.fill();
@assert pixel 50,25 == 0,0,0,0; @moz-todo
expected: green
- name: 2d.path.beginPath
testing:
- 2d.path.beginPath
background: "#0f0"
code: |
ctx.rect(0, 0, 100, 50);
ctx.beginPath();
ctx.fillStyle = '#f00';
ctx.fill();
@assert pixel 50,25 == 0,0,0,0;
expected: green
- name: 2d.path.moveTo.basic
testing:
- 2d.path.moveTo
background: "#f00"
code: |
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
testing:
- 2d.path.moveTo
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.moveTo.multiple
testing:
- 2d.path.moveTo
background: "#f00"
code: |
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.closePath.empty
testing:
- 2d.path.closePath.empty
background: "#0f0"
code: |
ctx.closePath();
ctx.fillStyle = '#f00';
ctx.fill();
@assert pixel 50,25 == 0,0,0,0;
expected: green
- name: 2d.path.closePath.newline
testing:
- 2d.path.closePath.nonempty
background: "#f00"
code: |
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
testing:
- 2d.path.closePath.nonempty
background: "#f00"
code: |
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.emptysubpath
testing:
- 2d.path.lineTo.empty
#mozilla: { bug: TODO }
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.lineTo(0, 25);
ctx.lineTo(100, 25);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0; @moz-todo
expected: green
- name: 2d.path.lineTo.basic
testing:
- 2d.path.lineTo.nonempty
background: "#f00"
code: |
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
testing:
- 2d.path.lineTo.nonempty
background: "#f00"
code: |
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.quadraticCurveTo.emptysubpath
testing:
- 2d.path.quadratic.empty
#mozilla: { bug: TODO }
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.quadraticCurveTo(0, 25, 0, 25);
ctx.quadraticCurveTo(100, 25, 100, 25);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0; @moz-todo
expected: green
- name: 2d.path.quadraticCurveTo.basic
testing:
- 2d.path.quadratic.nonempty
background: "#f00"
code: |
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
testing:
- 2d.path.quadratic.nonempty
background: "#f00"
code: |
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
testing:
- 2d.path.quadratic.nonempty
background: "#f00"
code: |
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.bezierCurveTo.emptysubpath
testing:
- 2d.path.bezier.empty
#mozilla: { bug: TODO }
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.bezierCurveTo(0, 25, 0, 25, 0, 25);
ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0; @moz-todo
expected: green
- name: 2d.path.bezierCurveTo.basic
testing:
- 2d.path.bezier.nonempty
background: "#f00"
code: |
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
testing:
- 2d.path.bezier.nonempty
background: "#f00"
code: |
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
testing:
- 2d.path.bezier.nonempty
background: "#f00"
code: |
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.arcTo.emptysubpath
testing:
- 2d.path.arcTo.empty
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.arcTo(0, 25, 0, 25, 0.1);
ctx.arcTo(100, 25, 100, 25, 0.1);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0;
expected: green
- name: 2d.path.arcTo.coincide.1
notes: &arcto Disagrees with spec - see suggestion
background: "#f00"
code: |
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.moveTo(0, 25);
ctx.arcTo(0, 25, 50, 1000, 1);
ctx.lineTo(100, 25);
ctx.stroke();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.path.arcTo.coincide.2
notes: *arcto
background: "#f00"
code: |
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 50;
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
notes: *arcto
background: "#f00"
code: |
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.moveTo(0, 25);
ctx.arcTo(100, 25, 200, 25, 1);
ctx.stroke();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.path.arcTo.collinear.2
notes: *arcto
background: "#f00"
code: |
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.moveTo(100, 25);
ctx.arcTo(200, 25, 150, 25, 1);
ctx.stroke();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.path.arcTo.collinear.3
notes: *arcto
background: "#f00"
code: |
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.moveTo(150, 25);
ctx.arcTo(200, 25, 100, 25, 1);
ctx.stroke();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.path.arcTo.shape.curve1
testing:
- 2d.path.arcTo.nonempty
code: |
var tol = 1; // 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;
expected: green
- name: 2d.path.arcTo.shape.curve2
testing:
- 2d.path.arcTo.nonempty
code: |
var tol = 1; // 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
testing:
- 2d.path.arcTo.nonempty
background: "#f00"
code: |
ctx.strokeStyle = '#0f0';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.moveTo(0, 25);
ctx.arcTo(200, 25, 200, 50, 10);
ctx.stroke();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.path.arcTo.shape.end
testing:
- 2d.path.arcTo.nonempty
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 50;
ctx.beginPath();
ctx.moveTo(-100, -100);
ctx.arcTo(-100, 25, 200, 25, 10);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0;
expected: green
- name: 2d.path.arcTo.negative
testing:
- 2d.path.arcTo.nonpositive
code: |
@assert throws INDEX_SIZE_ERR ctx.arcTo(0, 0, 0, 0, -1);
- name: 2d.path.arcTo.zero
notes: &arcto I think the spec should change for this - see suggestion
testing:
- 2d.path.arcTo.nonpositive
code: |
@assert throws INDEX_SIZE_ERR ctx.arcTo(0, 0, 0, 0, 0);
- name: 2d.path.arc.empty
testing:
- 2d.path.arc.nonempty
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.arc.nonempty
testing:
- 2d.path.arc.nonempty
background: "#f00"
code: |
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
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
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.angle.1
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.arc.angle.2
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.arc.angle.3
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.arc.angle.4
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
ctx.fillStyle = '#0f0';
ctx.beginPath();
ctx.moveTo(100, 0);
ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);
ctx.fill();
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.path.arc.zero.1
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 100;
ctx.beginPath();
ctx.arc(50, 25, 50, 0, 0, true);
ctx.stroke();
@assert pixel 50,20 == 0,0,0,0;
expected: green
- name: 2d.path.arc.zero.2
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 100;
ctx.beginPath();
ctx.arc(50, 25, 50, 0, 0, false);
ctx.stroke();
@assert pixel 50,20 == 0,0,0,0;
expected: green
- name: 2d.path.arc.zero.3
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.arc.zero.4
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
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.zero.5
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
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.zero.6
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
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.shape.1
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
ctx.lineWidth = 50;
ctx.strokeStyle = '#f00';
ctx.beginPath();
ctx.arc(50, 50, 50, 0, Math.PI, false);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0;
@assert pixel 1,1 == 0,0,0,0;
@assert pixel 98,1 == 0,0,0,0;
@assert pixel 1,48 == 0,0,0,0;
@assert pixel 20,48 == 0,0,0,0;
@assert pixel 98,48 == 0,0,0,0;
expected: green
- name: 2d.path.arc.shape.2
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
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
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.arc.shape.4
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
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;
expected: green
- name: 2d.path.arc.shape.5
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.arc.selfintersect.1
testing:
- 2d.path.arc.draw
background: "#0f0"
code: |
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 50,25 == 0,0,0,0;
expected: green
- name: 2d.path.arc.selfintersect.2
testing:
- 2d.path.arc.draw
background: "#f00"
code: |
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
testing:
- 2d.path.arc.nonpositive
#mozilla: { bug: TODO }
code: |
@assert throws INDEX_SIZE_ERR ctx.arc(0, 0, -1, 0, 0, true); @moz-todo
- name: 2d.path.arc.zero
testing:
- 2d.path.arc.nonpositive
#mozilla: { bug: TODO }
code: |
@assert throws INDEX_SIZE_ERR ctx.arc(0, 0, 0, 0, 0, true); @moz-todo
- name: 2d.path.arc.scale
desc: Scaled arcs are the right size
testing:
- 2d.path.transformation
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.rect.basic
testing:
- 2d.path.rect.subpath
background: "#f00"
code: |
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
testing:
- 2d.path.rect.subpath
background: "#0f0"
code: |
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,0,0,0;
expected: green
- name: 2d.path.rect.closed
testing:
- 2d.path.rect.closed
background: "#f00"
code: |
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
testing:
- 2d.path.rect.newsubpath
background: "#f00"
code: |
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
testing:
- 2d.path.rect.newsubpath
background: "#f00"
code: |
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
testing:
- 2d.path.rect.subpath
background: "#f00"
code: |
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
testing:
- 2d.path.rect.subpath
background: "#f00"
code: |
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
testing:
- 2d.path.rect.subpath
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 100;
ctx.beginPath();
ctx.rect(50, 25, 0, 0);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0;
expected: green
- name: 2d.path.rect.zero.4
testing:
- 2d.path.rect.subpath
background: "#f00"
code: |
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
testing:
- 2d.path.rect.subpath
background: "#0f0"
code: |
ctx.strokeStyle = '#f00';
ctx.lineWidth = 50;
ctx.moveTo(0, 0);
ctx.rect(100, 25, 0, 0);
ctx.stroke();
@assert pixel 50,25 == 0,0,0,0;
expected: green
- name: 2d.path.rect.zero.6
testing:
- 2d.path.rect.subpath
#mozilla: { bug: TODO }
background: "#0f0"
code: |
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,0,0,0; @moz-todo
expected: green
- name: 2d.path.rect.negative
testing:
- 2d.path.rect.negative
#mozilla: { bug: TODO }
code: |
@assert throws INDEX_SIZE_ERR ctx.rect(0, 0, -1, 10); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.rect(0, 0, 10, -1); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.rect(0, 0, -1, -1); @moz-todo
- name: 2d.path.rect.selfintersect
#mozilla: { bug: TODO }
background: "#f00"
code: |
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.fill.winding.add
testing:
- 2d.path.fill.basic
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
testing:
- 2d.path.fill.basic
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
testing:
- 2d.path.fill.basic
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
testing:
- 2d.path.fill.basic
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
testing:
- 2d.path.fill.closed
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
testing:
- 2d.path.fill.closed
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.union
desc: Strokes in opposite directions are unioned, not subtracted
testing:
- 2d.path.stroke.basic
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
testing:
- 2d.path.stroke.basic
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
testing:
- 2d.path.transformation
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
testing:
- 2d.path.transformation
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
testing:
- 2d.path.transformation
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.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.transformation.basic
testing:
- 2d.path.transformation
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
testing:
- 2d.path.transformation
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.rect(0, 0, 100, 50);
ctx.fill();
ctx.translate(-100, 0);
ctx.fillStyle = '#0f0';
ctx.fill();
@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
testing:
- 2d.path.transformation
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
testing:
- 2d.path.clip.basic
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
testing:
- 2d.path.clip.basic
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
testing:
- 2d.path.clip.basic
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
testing:
- 2d.path.clip.basic
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
testing:
- 2d.path.clip.basic
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
testing:
- 2d.path.clip.basic
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.lineTo(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
testing:
- 2d.path.clip.closed
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#0f0';
ctx.beginPath();
ctx.lineTo(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
testing:
- 2d.path.isPointInPath
code: |
ctx.rect(0, 0, 20, 20);
@assert ctx.isPointInPath(10, 10) === true;
- name: 2d.path.isPointInPath.basic.2
testing:
- 2d.path.isPointInPath
code: |
ctx.rect(20, 0, 20, 20);
@assert ctx.isPointInPath(10, 10) === false;
- name: 2d.path.isPointInPath.empty
testing:
- 2d.path.isPointInPath
code: |
@assert ctx.isPointInPath(0, 0) === false;
- name: 2d.path.isPointInPath.unclosed
testing:
- 2d.path.isPointInPath
code: |
ctx.moveTo(0, 0);
ctx.lineTo(20, 0);
ctx.lineTo(20, 20);
ctx.lineTo(0, 20);
@assert ctx.isPointInPath(10, 10) === true;
- name: 2d.path.isPointInPath.winding
testing:
- 2d.path.isPointInPath
code: |
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
testing:
- 2d.path.isPointInPath
mozilla: { bug: 405300 }
code: |
ctx.translate(50, 0);
ctx.rect(0, 0, 20, 20);
@assert ctx.isPointInPath(-40, 10) === false;
@assert ctx.isPointInPath(10, 10) === false; @moz-todo
@assert ctx.isPointInPath(49, 10) === false;
@assert ctx.isPointInPath(51, 10) === true; @moz-todo
@assert ctx.isPointInPath(69, 10) === true; @moz-todo
@assert ctx.isPointInPath(71, 10) === false;
- name: 2d.path.isPointInPath.transform.2
testing:
- 2d.path.isPointInPath
mozilla: { bug: 405300 }
code: |
ctx.rect(0, 0, 20, 20);
ctx.translate(50, 0);
@assert ctx.isPointInPath(-40, 10) === false; @moz-todo
@assert ctx.isPointInPath(10, 10) === false;
@assert ctx.isPointInPath(49, 10) === false;
@assert ctx.isPointInPath(51, 10) === true; @moz-todo
@assert ctx.isPointInPath(69, 10) === true; @moz-todo
@assert ctx.isPointInPath(71, 10) === false;
- name: 2d.path.isPointInPath.transform.3
testing:
- 2d.path.isPointInPath
mozilla: { bug: 405300 }
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; @moz-todo
@assert ctx.isPointInPath(69, 10) === true; @moz-todo
@assert ctx.isPointInPath(71, 10) === false;
- name: 2d.drawImage.3arg
testing:
- 2d.drawImage.defaultsource
- 2d.drawImage.defaultdest
images:
- red.png
- green.png
code: |
ctx.drawImage(document.getElementById('green.png'), 0, 0);
ctx.drawImage(document.getElementById('red.png'), -100, 0);
ctx.drawImage(document.getElementById('red.png'), 100, 0);
ctx.drawImage(document.getElementById('red.png'), 0, -50);
ctx.drawImage(document.getElementById('red.png'), 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;
expected: green
- name: 2d.drawImage.5arg
testing:
- 2d.drawImage.defaultsource
images:
- red.png
- green.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('green.png'), 50, 0, 50, 50);
ctx.drawImage(document.getElementById('red.png'), 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;
expected: green
- name: 2d.drawImage.9arg.basic
testing:
- 2d.drawImage.paint
images:
- green.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('green.png'), 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
testing:
- 2d.drawImage.paint
images:
- rgrg-256x256.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('rgrg-256x256.png'), 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
testing:
- 2d.drawImage.paint
images:
- rgrg-256x256.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('rgrg-256x256.png'), 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
testing:
- 2d.drawImage.paint
images:
- red.png
- green.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50);
ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -100, 0, 100, 50);
ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 100, 50);
ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -50, 100, 50);
ctx.drawImage(document.getElementById('red.png'), 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;
expected: green
- name: 2d.drawImage.9arg.destsize
testing:
- 2d.drawImage.paint
images:
- red.png
- green.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('green.png'), 1, 1, 1, 1, 0, 0, 100, 50);
ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -50, 0, 50, 50);
ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 50, 50);
ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -25, 100, 25);
ctx.drawImage(document.getElementById('red.png'), 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;
expected: green
- name: 2d.drawImage.canvas
testing:
- 2d.drawImage.paint
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;
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
#mozilla: { bug: TODO }
testing:
- 2d.drawImage.type
code: |
@assert throws TYPE_MISMATCH_ERR ctx.drawImage(null, 0, 0); @moz-todo
- name: 2d.drawImage.wrongtype
#mozilla: { bug: TODO }
testing:
- 2d.drawImage.type
code: |
@assert throws TYPE_MISMATCH_ERR ctx.drawImage(undefined, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.drawImage(0, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.drawImage("", 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.drawImage(document.createElement('p'), 0, 0); @moz-todo
- name: 2d.drawImage.floatsource
testing:
- 2d.drawImage.paint
images:
- green.png
code: |
ctx.drawImage(document.getElementById('green.png'), 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
notes: Unspecified behaviour
#mozilla: { bug: TODO }
images:
- green.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('green.png'), 10, 10, 0, 1, 0, 0, 30, 50);
ctx.drawImage(document.getElementById('green.png'), 10, 10, 1, 0, 30, 0, 40, 50);
ctx.drawImage(document.getElementById('green.png'), 10, 10, 0, 0, 70, 0, 30, 50);
@assert pixel 15,25 ==~ 0,255,0,255; @moz-todo
@assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
@assert pixel 85,25 ==~ 0,255,0,255; @moz-todo
expected: green
- name: 2d.drawImage.negativesource
notes: Unspecified behaviour
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 10, 10, -1, 1, 0, 0, 100, 50);
expected: green
- name: 2d.drawImage.negativedest
testing:
- 2d.drawImage.negativedest
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 1, 0, 50, -100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 1, 0, 50, 100, -50);
expected: green
- name: 2d.drawImage.outsidesource
testing:
- 2d.drawImage.outsidesource
#mozilla: { bug: TODO }
images:
- green.png
- red.png
code: |
ctx.drawImage(document.getElementById('green.png'), 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), -0.001, 0, 100, 50, 0, 0, 100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, -0.001, 100, 50, 0, 0, 100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100.001, 50, 0, 0, 100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50.001, 0, 0, 100, 50);
@assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo
@assert pixel 50,25 ==~ 0,255,0,255; @moz-todo
expected: green
- name: 2d.drawImage.incomplete
testing:
- 2d.drawImage.incomplete
#mozilla: { bug: TODO }
code: |
var img = new Image();
@assert img.complete === false; @moz-todo
@assert throws INVALID_STATE_ERR ctx.drawImage(img, 0, 0); @moz-todo
# TODO: see 2d.pattern.image.incomplete2,3,4 and repeat them here once they're fixed
- name: 2d.drawImage.broken
testing:
- 2d.drawImage.incomplete
#mozilla: { bug: TODO }
images:
- broken.png
code: |
var img = document.getElementById('broken.png');
@assert img.complete === false; @moz-todo
@assert throws INVALID_STATE_ERR ctx.drawImage(img, 0, 0); @moz-todo
- name: 2d.drawImage.path
testing:
- 2d.drawImage.unaffect
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.rect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('red.png'), 0, 0);
ctx.fill();
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- name: 2d.drawImage.transform
testing:
- 2d.drawImage.subject
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.translate(100, 0);
ctx.drawImage(document.getElementById('red.png'), 0, 0);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
# TODO: drawImage shadows
- name: 2d.drawImage.alpha
testing:
- 2d.drawImage.subject
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.globalAlpha = 0;
ctx.drawImage(document.getElementById('red.png'), 0, 0);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- name: 2d.drawImage.clip
testing:
- 2d.drawImage.subject
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.rect(-10, -10, 1, 1);
ctx.clip();
ctx.drawImage(document.getElementById('red.png'), 0, 0);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- name: 2d.drawImage.composite
testing:
- 2d.drawImage.subject
images:
- red.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.globalCompositeOperation = 'destination-over';
ctx.drawImage(document.getElementById('red.png'), 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
images:
- redtransparent.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.drawImage(document.getElementById('redtransparent.png'), -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.imageData.get.basic
testing:
- 2d.imageData.get.basic
code: |
@assert ctx.getImageData(0, 0, 100, 50) !== null;
- name: 2d.imageData.get.sourcepos
testing:
- 2d.imageData.get.basic
code: |
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#fff';
ctx.fillRect(20, 10, 60, 30);
var imgdata1 = ctx.getImageData(10, 5, 1, 1);
@assert imgdata1.data[0] < 50;
var imgdata2 = ctx.getImageData(30, 20, 1, 1);
@assert imgdata2.data[0] > 200;
- name: 2d.imageData.get.values
testing:
- 2d.imageData.get.range
code: |
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#fff';
ctx.fillRect(20, 10, 60, 30);
var imgdata1 = ctx.getImageData(10, 5, 1, 1);
@assert imgdata1.data[0] === 0;
var imgdata2 = ctx.getImageData(30, 20, 1, 1);
@assert imgdata2.data[0] === 255;
- name: 2d.imageData.get.sourcesize
testing:
- 2d.imageData.get.basic
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.properties
testing:
- 2d.imageData.get.properties
code: |
var imgdata = ctx.getImageData(0, 0, 100, 50);
@assert typeof(imgdata.width) == 'number';
@assert typeof(imgdata.height) == 'number';
@assert typeof(imgdata.data) == 'object';
@assert imgdata.data.length === imgdata.width*imgdata.height*4;
- name: 2d.imageData.get.dataarray
desc: ImageData.data acts enough like an Array
testing:
- 2d.imageData.get.properties
code: |
var imgdata = ctx.getImageData(0, 0, 1, 1);
var data = imgdata.data.join(';');
@assert data =~ /^0;0;0;0/;
- name: 2d.imageData.get.outside.1
testing:
- 2d.imageData.get.outside
mozilla: { disabled } # TODO: report bug?
code: |
var imgdata = ctx.getImageData(-5, 20, 10, 10);
@assert imgdata.data[0] === 0;
@assert imgdata.data[1] === 0;
@assert imgdata.data[2] === 0;
@assert imgdata.data[3] === 0;
- name: 2d.imageData.get.outside.2
testing:
- 2d.imageData.get.outside
mozilla: { disabled } # TODO: report bug?
code: |
var imgdata1 = ctx.getImageData(-20, 20, 10, 10);
@assert imgdata1.data[0] === 0;
@assert imgdata1.data[1] === 0;
@assert imgdata1.data[2] === 0;
@assert imgdata1.data[3] === 0;
var imgdata2 = ctx.getImageData(40, -20, 10, 10);
@assert imgdata2.data[0] === 0;
@assert imgdata2.data[1] === 0;
@assert imgdata2.data[2] === 0;
@assert imgdata2.data[3] === 0;
var imgdata3 = ctx.getImageData(110, 20, 10, 10);
@assert imgdata3.data[0] === 0;
@assert imgdata3.data[1] === 0;
@assert imgdata3.data[2] === 0;
@assert imgdata3.data[3] === 0;
var imgdata4 = ctx.getImageData(40, 60, 10, 10);
@assert imgdata4.data[0] === 0;
@assert imgdata4.data[1] === 0;
@assert imgdata4.data[2] === 0;
@assert imgdata4.data[3] === 0;
- name: 2d.imageData.get.nonpremul
testing:
- 2d.imageData.get.premul
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.order.cols
testing:
- 2d.imageData.get.pixelorder
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.floor(imgdata.width/2*4)] === 255;
@assert imgdata.data[(imgdata.height/2)*imgdata.width*4] === 0;
- name: 2d.imageData.get.order.rows
testing:
- 2d.imageData.get.pixelorder
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
testing:
- 2d.imageData.get.pixelorder
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;
- name: 2d.imageData.get.order.alpha
testing:
- 2d.imageData.get.pixelorder
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.smallest
testing:
- 2d.imageData.get.smallest
code: |
var imgdata = ctx.getImageData(0, 0, 1, 1);
@assert imgdata.width > 0;
@assert imgdata.height > 0;
@assert imgdata.data.length === imgdata.width*imgdata.height*4;
- name: 2d.imageData.get.nonpositive
testing:
- 2d.imageData.get.nonpositive
#mozilla: { bug: TODO }
code: |
@assert throws INDEX_SIZE_ERR ctx.getImageData(10, 10, 1, 0); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.getImageData(10, 10, 0, 1); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.getImageData(10, 10, 0, 0); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.getImageData(10, 10, 1, -1); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.getImageData(10, 10, -1, 1); @moz-todo
@assert throws INDEX_SIZE_ERR ctx.getImageData(10, 10, -1, -1); @moz-todo
- name: 2d.imageData.get.nonfinite
#mozilla: { bug: TODO }
code: |
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(Infinity, 10, 1, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, Infinity, 1, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, 10, Infinity, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, 10, 1, Infinity); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(-Infinity, 10, 1, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, -Infinity, 1, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, 10, -Infinity, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, 10, 1, -Infinity); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(NaN, 10, 1, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, NaN, 1, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, 10, NaN, 1); @moz-todo
@assert throws NOT_SUPPORTED_ERR ctx.getImageData(10, 10, 1, NaN); @moz-todo
- name: 2d.imageData.put.basic
testing:
- 2d.imageData.put.basic
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.alpha
testing:
- 2d.imageData.put.basic
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
testing:
- 2d.imageData.put.basic
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.outside
testing:
- 2d.imageData.put.basic
mozilla: { disabled } # TODO: report bug?
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, 0);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- name: 2d.imageData.put.type.correct
desc: putImageData accepts a correctly-constructed image data object
testing:
- 2d.imageData.put.type
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50)
var imgdata1 = ctx.getImageData(45, 20, 10, 10);
ctx.fillStyle = '#f00';
ctx.fillRect(45, 20, 10, 10)
var data = [];
for (var i = 0; i < imgdata1.data.length; ++i)
data[i] = imgdata1.data[i];
var imgdata2 = { width: imgdata1.width, height: imgdata1.height, data: data };
ctx.putImageData(imgdata2, 45, 20);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- name: 2d.imageData.put.type.onepixel
desc: putImageData accepts a correctly-constructed 1x1 image data object
testing:
- 2d.imageData.put.type
code: |
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 0] }, 0, 0);
@assert true; // no exception
- name: 2d.imageData.put.type.extra
desc: putImageData accepts an image data object with extra attributes
testing:
- 2d.imageData.put.type
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50)
var imgdata1 = ctx.getImageData(45, 20, 10, 10);
ctx.fillStyle = '#f00';
ctx.fillRect(45, 20, 10, 10)
var data = [];
for (var i = 0; i < imgdata1.data.length; ++i)
data[i] = imgdata1.data[i];
var imgdata2 = { width: imgdata1.width, height: imgdata1.height, data: data, extra: 123 };
ctx.putImageData(imgdata2, 45, 20);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- name: 2d.imageData.put.type.missing
desc: putImageData does not accept an image data object with missing attributes
testing:
- 2d.imageData.put.type
#mozilla: { bug: TODO }
code: |
var imgdata1 = ctx.getImageData(0, 0, 10, 10);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ height: imgdata1.height, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: imgdata1.width, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: imgdata1.width, height: imgdata1.height }, 0, 0); @moz-todo
- name: 2d.imageData.put.type.invalidsize
desc: putImageData does not accept an image data object with incorrect sizes
testing:
- 2d.imageData.put.type
#mozilla: { bug: TODO }
code: |
var imgdata1 = ctx.getImageData(0, 0, 10, 10);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 0, height: imgdata1.height, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: -1, height: imgdata1.height, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: NaN, height: imgdata1.height, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: imgdata1.width, height: 0, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: imgdata1.width, height: -1, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: imgdata1.width, height: NaN, data: imgdata1.data }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 1, data: [] }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 1, data: [0] }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 1, data: [0,0] }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 1, data: [0,0,0] }, 0, 0); @moz-todo
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 1, data: [0,0,0,0,0] }, 0, 0); @moz-todo
- name: 2d.imageData.put.type.zerosize
desc: putImageData does not accept an image data object with zero size
testing:
- 2d.imageData.put.type
code: |
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 0, height: 1, data: [] }, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 0, data: [] }, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 0.1, height: 1, data: [] }, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 0.1, data: [] }, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 0, height: 0, data: [] }, 0, 0);
- name: 2d.imageData.put.type.noninteger
desc: putImageData does not accept an image data object with non-integer size
testing:
- 2d.imageData.put.type
code: |
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1.1, height: 1, data: [0, 0, 0, 0] }, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1, height: 1.1, data: [0, 0, 0, 0] }, 0, 0);
@assert throws TYPE_MISMATCH_ERR ctx.putImageData({ width: 1.1, height: 1.1, data: [0, 0, 0, 0] }, 0, 0);
- name: 2d.imageData.put.clamp
code: |
ctx.putImageData({ width: 1, height: 1, data: [-1, 0, 1, 255] }, 0, 0);
ctx.putImageData({ width: 1, height: 1, data: [254, 255, 256, 255] }, 1, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, -1] }, 2, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 0] }, 3, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 1] }, 4, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 254] }, 5, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 255] }, 6, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 256] }, 7, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, Infinity] }, 0, 1);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, -Infinity] }, 1, 1);
ctx.putImageData({ width: 1, height: 1, data: [Infinity, Infinity, Infinity, 255] }, 2, 1);
ctx.putImageData({ width: 1, height: 1, data: [-Infinity, -Infinity, -Infinity, 255] }, 3, 1);
// TODO: what happens with NaN?
@assert pixel 0,0 == 0,0,1,255;
@assert pixel 1,0 == 254,255,255,255;
@assert pixel 2,0 == 0,0,0,0;
@assert pixel 3,0 == 0,0,0,0;
@assert pixel 4,0 == 0,0,0,1;
@assert pixel 5,0 == 0,0,0,254;
@assert pixel 6,0 == 0,0,0,255;
@assert pixel 7,0 == 0,0,0,255;
@assert pixel 0,1 == 0,0,0,255;
@assert pixel 1,1 == 0,0,0,0;
@assert pixel 2,1 == 255,255,255,255;
@assert pixel 3,1 == 0,0,0,255;
# TODO: create a useful 'expected' image here
- name: 2d.imageData.put.round
code: |
ctx.putImageData({ width: 1, height: 1, data: [0.1, 0.9, 1.1, 255] }, 0, 0);
ctx.putImageData({ width: 1, height: 1, data: [1.1, 1.9, 2.1, 255] }, 1, 0);
ctx.putImageData({ width: 1, height: 1, data: [0.5, 1.5, 2.5, 255] }, 2, 0);
ctx.putImageData({ width: 1, height: 1, data: [252.5, 253.5, 254.5, 255] }, 3, 0);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 254.5] }, 0, 1);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 253.5] }, 1, 1);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 252.5] }, 2, 1);
ctx.putImageData({ width: 1, height: 1, data: [0, 0, 0, 251.5] }, 3, 1);
@assert pixel 0,0 == 0,1,1,255;
@assert pixel 1,0 == 1,2,2,255;
@assert pixel 2,0 == 0,2,2,255;
@assert pixel 3,0 == 252,254,254,255;
@assert pixel 0,1 == 0,0,0,254;
@assert pixel 1,1 == 0,0,0,254;
@assert pixel 2,1 == 0,0,0,252;
@assert pixel 3,1 == 0,0,0,252;
# TODO: create a useful 'expected' image here
- name: 2d.imageData.put.unchanged
testing:
- 2d.imageData.unchanged
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
testing:
- 2d.imageData.transform
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.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.path
testing:
- 2d.imageData.put.basic
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
- name: 2d.shadow.attributes.shadowBlur.1
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 = 1;
ctx.shadowBlur = -2;
@assert ctx.shadowBlur === 1;
ctx.shadowBlur = 0;
@assert ctx.shadowBlur === 0;
- name: 2d.shadow.attributes.shadowBlur.2
code: |
@assert throws NOT_SUPPORTED_ERR ctx.shadowBlur = Infinity;
@assert throws NOT_SUPPORTED_ERR ctx.shadowBlur = -Infinity;
@assert throws NOT_SUPPORTED_ERR ctx.shadowBlur = NaN;
- name: 2d.shadow.attributes.shadowOffset.1
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 = 1e6;
ctx.shadowOffsetY = 1e6;
@assert ctx.shadowOffsetX === 1e6;
@assert ctx.shadowOffsetY === 1e6;
- name: 2d.shadow.attributes.shadowOffset.2
code: |
@assert throws NOT_SUPPORTED_ERR ctx.shadowOffsetX = Infinity;
@assert throws NOT_SUPPORTED_ERR ctx.shadowOffsetX = -Infinity;
@assert throws NOT_SUPPORTED_ERR ctx.shadowOffsetX = NaN;
@assert throws NOT_SUPPORTED_ERR ctx.shadowOffsetY = Infinity;
@assert throws NOT_SUPPORTED_ERR ctx.shadowOffsetY = -Infinity;
@assert throws NOT_SUPPORTED_ERR ctx.shadowOffsetY = NaN;
- name: 2d.shadow.attributes.shadowColor.1
code: |
ctx.shadowColor = 'lime';
@assert ctx.shadowColor === '#00ff00';
ctx.shadowColor = 'RGBA(0,255, 0,0)';
@assert ctx.shadowColor === 'rgba(0, 255, 0, 0.0)';
- name: 2d.shadow.attributes.shadowColor.2
code: |
ctx.shadowColor = '#00ff00';
ctx.shadowColor = 'bogus';
@assert ctx.shadowColor === '#00ff00';
ctx.shadowColor = ctx;
@assert ctx.shadowColor === '#00ff00';
ctx.shadowColor = undefined;
@assert ctx.shadowColor === '#00ff00';
- name: 2d.shadow.basic.1
notes: &shadow Assumes this definition.
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.basic.2
notes: *shadow
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = '#f00';
ctx.shadowColor = '#f00';
ctx.fillRect(0, -50, 100, 50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.shadow.offset.positiveX
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
images:
- red.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.shadowColor = '#0f0';
ctx.shadowOffsetY = 50;
ctx.drawImage(document.getElementById('red.png'), 0, -50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.shadow.image.transparent.1
notes: *shadow
images:
- transparent.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.shadowColor = '#f00';
ctx.shadowOffsetY = 50;
ctx.drawImage(document.getElementById('transparent.png'), 0, -50);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.shadow.image.transparent.2
notes: *shadow
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';
ctx.drawImage(document.getElementById('redtransparent.png'), 50, -50);
ctx.shadowColor = '#f00';
ctx.drawImage(document.getElementById('redtransparent.png'), -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
- name: 2d.shadow.image.alpha
notes: *shadow
images:
- transparent50.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.shadowOffsetY = 50;
ctx.shadowColor = '#00f';
ctx.drawImage(document.getElementById('transparent50.png'), 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()
- name: 2d.shadow.image.section
notes: *shadow
images:
- redtransparent.png
code: |
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50);
ctx.shadowOffsetY = 50;
ctx.shadowColor = '#f00';
ctx.drawImage(document.getElementById('redtransparent.png'), 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
- name: 2d.shadow.image.scale
notes: *shadow
images:
- redtransparent.png
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.shadowOffsetY = 50;
ctx.shadowColor = '#0f0';
ctx.drawImage(document.getElementById('redtransparent.png'), 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
- name: 2d.shadow.canvas.basic
notes: *shadow
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 = '#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
- name: 2d.shadow.canvas.transparent.1
notes: *shadow
code: |
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);
@assert pixel 50,25 == 0,255,0,255;
expected: green
- name: 2d.shadow.canvas.transparent.2
notes: *shadow
code: |
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);
@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.canvas.alpha
notes: *shadow
images:
- transparent50.png
code: |
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);
@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.pattern.basic
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
images:
- red.png
code: |
var pattern = ctx.createPattern(document.getElementById('red.png'), '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
- name: 2d.shadow.pattern.transparent.1
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
images:
- transparent.png
code: |
var pattern = ctx.createPattern(document.getElementById('transparent.png'), '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
- name: 2d.shadow.pattern.transparent.2
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
images:
- redtransparent.png
code: |
var pattern = ctx.createPattern(document.getElementById('redtransparent.png'), '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
- name: 2d.shadow.pattern.alpha
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
images:
- transparent50.png
code: |
var pattern = ctx.createPattern(document.getElementById('transparent50.png'), '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()
- name: 2d.shadow.gradient.basic
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
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
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
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
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
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
# http://bugs.webkit.org/show_bug.cgi?id=15266
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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):
if x < 8:
sigma = x/2.0
else:
sigma = math.sqrt(x*2)
filter = [math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma) for i in range(-24, 26)]
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
notes: *shadow
code: |
ctx.fillStyle = '#ff0';
ctx.fillRect(0, 0, 100, 50);
ctx.shadowColor = '#00f';
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 555.6;
ctx.fillRect(-200, -200, 200, 400);
expected: |
size 100 50
import math
sigma = math.sqrt(555.6*2)
filter = [math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma) for i in range(-200, 100)]
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
notes: *shadow
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
# http://bugs.webkit.org/show_bug.cgi?id=15265
notes: *shadow
code: |
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
ctx.globalCompositeOperation = 'xor';
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.composite.4
# http://bugs.webkit.org/show_bug.cgi?id=15265
notes: *shadow
code: |
ctx.globalCompositeOperation = 'destination-over';
ctx.shadowColor = '#0f0';
ctx.fillStyle = '#f00';
ctx.fillRect(0, 0, 100, 50);
@assert pixel 50,25 ==~ 0,255,0,255;
expected: green
- meta: |
import re
for t in tests:
n = t['name']
if (
n.startswith('2d.composite.uncovered.') # bug ???
or n.startswith('2d.path.arcTo.') # unreported
or n.startswith('2d.shadow.') # bug ???
or n == '2d.composite.solid.xor' # bug ???
or n.startswith('context.') # bug 401788
):
t.setdefault('mozilla', {})
t['mozilla'].setdefault('disabled', None)