blob: 6c9cb6d08ec3e6858a704177bc9e0bef232e037f [file] [log] [blame]
let ctx = null;
// 2x2 red square
let image = document.createElement("img");
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABNJREFUCB1j/M/AAEQMDEwgAgQAHxcCAmtAm/sAAAAASUVORK5CYII=";
// Invalid video
let video = document.createElement("video");
// Blank canvas
let canvas = document.createElement("canvas");
canvas.width = 2;
canvas.height = 2;
let linearGradient = null;
let radialGradient = null;
let pattern = null;
let path12 = new Path2D("M 1 2");
let path34 = new Path2D("M 3 4");
let imageData14 = new ImageData(1, 4);
let imageData23 = new ImageData(2, 3);
let bitmap = null;
async function load() {
ctx = canvas.getContext("2d");
linearGradient = ctx.createLinearGradient(1, 2, 3, 4);
radialGradient = ctx.createRadialGradient(1, 2, 3, 4, 5, 6);
pattern = ctx.createPattern(image, "no-repeat");
bitmap = await createImageBitmap(image);
ctx.save();
cancelActions();
runTest();
}
function ignoreException(func){
try {
func();
} catch (e) { }
}
let requestAnimationFrameId = NaN;
let saveCount = 1;
function cancelActions() {
for (let i = 0; i < saveCount; ++i)
ctx.restore();
ctx.restore(); // Ensures the state is reset between test cases.
cancelAnimationFrame(requestAnimationFrameId);
requestAnimationFrameId = NaN;
ctx.save(); // Ensures the state is reset between test cases.
ctx.save(); // This matches the `restore` call in `performActions`.
saveCount = 1;
ctx.resetTransform();
ctx.beginPath();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
function performActions() {
let frames = [
() => {
ignoreException(() => ctx.arc(1, 2, 3, 4, 5));
ignoreException(() => ctx.arc(6, 7, 8, 9, 10, true));
},
() => {
ignoreException(() => ctx.arcTo(1, 2, 3, 4, 5));
},
() => {
ctx.beginPath();
},
() => {
ctx.bezierCurveTo(1, 2, 3, 4, 5, 6);
},
() => {
ctx.clearRect(1, 2, 3, 4);
},
() => {
ctx.clearShadow();
},
() => {
ctx.clip();
ctx.clip("evenodd");
ctx.clip(path12);
ctx.clip(path34, "evenodd");
},
() => {
ctx.closePath();
},
() => {
ignoreException(() => ctx.createImageData(imageData14));
ignoreException(() => ctx.createImageData(2, 3));
},
() => {
ignoreException(() => ctx.createLinearGradient(1, 2, 3, 4));
},
() => {
ignoreException(() => ctx.createPattern(image, "testA"));
ignoreException(() => ctx.createPattern(video, "testB"));
ignoreException(() => ctx.createPattern(canvas, "testC"));
ignoreException(() => ctx.createPattern(bitmap, "testD"));
},
() => {
ignoreException(() => ctx.createRadialGradient(1, 2, 3, 4, 5, 6));
},
() => {
ctx.direction;
ctx.direction = "test";
},
() => {
ctx.drawFocusIfNeeded(document.body);
ctx.drawFocusIfNeeded(path12, document.body);
},
() => {
ignoreException(() => ctx.drawImage(image, 11, 12));
ignoreException(() => ctx.drawImage(image, 13, 14, 15, 16));
ignoreException(() => ctx.drawImage(image, 17, 18, 19, 110, 111, 112, 113, 114));
ignoreException(() => ctx.drawImage(video, 21, 22));
ignoreException(() => ctx.drawImage(video, 23, 24, 25, 26));
ignoreException(() => ctx.drawImage(video, 27, 28, 29, 210, 211, 212, 213, 214));
ignoreException(() => ctx.drawImage(canvas, 31, 32));
ignoreException(() => ctx.drawImage(canvas, 33, 34, 35, 36));
ignoreException(() => ctx.drawImage(canvas, 37, 38, 39, 310, 311, 312, 313, 314));
ignoreException(() => ctx.drawImage(bitmap, 41, 42));
ignoreException(() => ctx.drawImage(bitmap, 43, 44, 45, 46));
ignoreException(() => ctx.drawImage(bitmap, 47, 48, 49, 410, 411, 412, 413, 414));
},
() => {
ctx.drawImageFromRect(image, 1, 2, 3, 4, 5, 6, 7, 8)
ctx.drawImageFromRect(image, 9, 10, 11, 12, 13, 14, 15, 16, "test");
},
() => {
ignoreException(() => ctx.ellipse(1, 2, 3, 4, 5, 6, 7));
ignoreException(() => ctx.ellipse(8, 9, 10, 11, 12, 13, 14, true));
},
() => {
ctx.fill();
ctx.fill("evenodd");
ctx.fill(path12);
ctx.fill(path34, "evenodd");
},
() => {
ctx.fillRect(1, 2, 3, 4);
},
() => {
ctx.fillStyle;
ctx.fillStyle = "test";
ctx.fillStyle = linearGradient;
ctx.fillStyle = radialGradient;
ctx.fillStyle = pattern;
},
() => {
ctx.fillText("testA", 1, 2);
ctx.fillText("testB", 3, 4, 5);
},
() => {
ctx.font;
ctx.font = "test";
},
() => {
ignoreException(() => ctx.getImageData(1, 2, 3, 4));
},
() => {
ctx.getLineDash();
},
() => {
ctx.getTransform();
},
() => {
ctx.globalAlpha;
ctx.globalAlpha = 0;
},
() => {
ctx.globalCompositeOperation;
ctx.globalCompositeOperation = "test";
},
() => {
ctx.imageSmoothingEnabled;
ctx.imageSmoothingEnabled = true;
},
() => {
ctx.imageSmoothingQuality;
ctx.imageSmoothingQuality = "low";
},
() => {
ctx.isPointInPath(path12, 5, 6);
ctx.isPointInPath(path34, 7, 8, "evenodd");
ctx.isPointInPath(9, 10);
ctx.isPointInPath(11, 12, "evenodd");
},
() => {
ctx.isPointInStroke(path12, 3, 4);
ctx.isPointInStroke(5, 6);
},
() => {
ctx.lineCap;
ctx.lineCap = "test";
},
() => {
ctx.lineDashOffset;
ctx.lineDashOffset = 1;
},
() => {
ctx.lineJoin;
ctx.lineJoin = "test";
},
() => {
ctx.lineTo(1, 2);
},
() => {
ctx.lineWidth;
ctx.lineWidth = 1;
},
() => {
ctx.measureText("test");
},
() => {
ctx.miterLimit;
ctx.miterLimit = 1;
},
() => {
ctx.moveTo(1, 2);
},
() => {
ctx.putImageData(imageData14, 5, 6);
ctx.putImageData(imageData23, 7, 8, 9, 10, 11, 12);
},
() => {
ctx.quadraticCurveTo(1, 2, 3, 4);
},
() => {
ctx.rect(1, 2, 3, 4);
},
() => {
ctx.resetTransform();
},
() => {
ctx.restore();
--saveCount;
},
() => {
ctx.rotate(1);
},
() => {
ctx.save();
++saveCount;
},
() => {
ctx.scale(1, 2);
},
() => {
ctx.setAlpha();
ctx.setAlpha(1);
},
() => {
ctx.setCompositeOperation();
ctx.setCompositeOperation("test");
},
() => {
ctx.setFillColor("testA");
ctx.setFillColor("testB", 1);
ctx.setFillColor(2);
ctx.setFillColor(3, 4);
ctx.setFillColor(5, 6, 7, 8);
},
() => {
ctx.setLineCap();
ctx.setLineCap("test");
},
() => {
ctx.setLineDash([1, 2]);
},
() => {
ctx.setLineJoin();
ctx.setLineJoin("test");
},
() => {
ctx.setLineWidth();
ctx.setLineWidth(1);
},
() => {
ctx.setMiterLimit();
ctx.setMiterLimit(1);
},
() => {
ctx.setShadow(1, 2, 3);
ctx.setShadow(4, 5, 6, "test", 7);
ctx.setShadow(8, 9, 10, 11);
ctx.setShadow(12, 13, 14, 15, 16);
ctx.setShadow(17, 18, 19, 20, 21, 22, 23);
ctx.setShadow(24, 25, 26, 27, 28, 29, 30, 31);
},
() => {
ctx.setStrokeColor("testA");
ctx.setStrokeColor("testB", 1);
ctx.setStrokeColor(2);
ctx.setStrokeColor(3, 4);
ctx.setStrokeColor(5, 6, 7, 8);
},
() => {
ctx.setTransform(1, 2, 3, 4, 5, 6);
ignoreException(() => ctx.setTransform());
ignoreException(() => ctx.setTransform(new DOMMatrix([7, 8, 9, 10, 11, 12])));
},
() => {
ctx.shadowBlur;
ctx.shadowBlur = 1;
},
() => {
ctx.shadowColor;
ctx.shadowColor = "test";
},
() => {
ctx.shadowOffsetX;
ctx.shadowOffsetX = 1;
},
() => {
ctx.shadowOffsetY;
ctx.shadowOffsetY = 1;
},
() => {
ctx.stroke();
ctx.stroke(path12);
},
() => {
ctx.strokeRect(1, 2, 3, 4);
},
() => {
ctx.strokeStyle;
ctx.strokeStyle = "test";
ctx.strokeStyle = linearGradient;
ctx.strokeStyle = radialGradient;
ctx.strokeStyle = pattern;
},
() => {
ctx.strokeText("testA", 1, 2);
ctx.strokeText("testB", 3, 4, 5);
},
() => {
ctx.textAlign;
ctx.textAlign = "test";
},
() => {
ctx.textBaseline;
ctx.textBaseline = "test";
},
() => {
ctx.transform(1, 2, 3, 4, 5, 6);
},
() => {
ctx.translate(1, 2);
},
() => {
ctx.webkitImageSmoothingEnabled;
ctx.webkitImageSmoothingEnabled = true;
},
() => {
ctx.webkitLineDash;
ctx.webkitLineDash = [1, 2];
},
() => {
ctx.webkitLineDashOffset;
ctx.webkitLineDashOffset = 1;
},
() => {
ctx.canvas.width;
ctx.canvas.width = 2;
},
() => {
ctx.canvas.height;
ctx.canvas.height = 2;
},
() => {
TestPage.dispatchEventToFrontend("LastFrame");
},
];
let index = 0;
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
};
executeFrameFunction();
}
function performConsoleActions() {
console.record(ctx, {name: "TEST"});
ctx.fill();
console.recordEnd(ctx);
ctx.stroke();
}
function performSavePreActions() {
cancelActions();
ctx.restore();
ctx.restore();
function saveAndSet(translateX, translateY, globalAlpha, globalCompositeOperation, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, lineDash, lineDashOffset, font, textAlign, textBaseline, direction, strokeStyle, fillStyle, imageSmoothingEnabled, imageSmoothingQuality) {
ctx.save()
ctx.translate(translateX, translateY)
ctx.globalAlpha = globalAlpha
ctx.globalCompositeOperation = globalCompositeOperation
ctx.lineWidth = lineWidth
ctx.lineCap = lineCap
ctx.lineJoin = lineJoin
ctx.miterLimit = miterLimit
ctx.shadowOffsetX = shadowOffsetX
ctx.shadowOffsetY = shadowOffsetY
ctx.shadowBlur = shadowBlur
ctx.shadowColor = shadowColor
ctx.setLineDash(lineDash)
ctx.lineDashOffset = lineDashOffset
ctx.font = font
ctx.textAlign = textAlign
ctx.textBaseline = textBaseline
ctx.direction = direction
ctx.strokeStyle = strokeStyle
ctx.fillStyle = fillStyle
ctx.imageSmoothingEnabled = imageSmoothingEnabled
ctx.imageSmoothingQuality = imageSmoothingQuality
// FIXME: Change the path, too.
}
saveAndSet(1, 0, 0.5, "source-in", 0.5, "round", "bevel", 20, 2, 3, 4, "#100000", [1, 2], 10, "20px sans-serif", "left", "top", "ltr", pattern, linearGradient, false, "medium")
saveAndSet(0, 1, 0, "difference", 2, "square", "round", 30, 4, 5, 6, "#001000", [3, 4], 11, "30px cursive", "right", "hanging", "inherit", linearGradient, pattern, true, "high")
saveAndSet(-1, -2, 0.75, "source-over", 3, "round", "bevel", 40, 6, 7, 8, "#000010", [5, 6], 12, "40px fantasy", "center", "ideographic", "rtl", "#200000", "#300000", false, "medium")
}
function performSavePostActions() {
ctx.fill();
}