chromium/third_party/blink/web_tests/fast/canvas/canvas-createImageBitmap-recursive.html

<html>
<head>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
description("Ensure correct behavior of drawImage with ImageBitmaps constructed from ImageBitmaps that are constructed from images (not pinned to memory) and canvases (pinned to memory).");

window.jsTestIsAsync = true;

function shouldBeFilled(x, y, w, h) {
    shouldBeGreen(x+2, y+2);
    shouldBeGreen(x+w-3, y+h-3);
    shouldBeGreen(x+w/2, y+h/2);
    shouldBeClear(x-2, y-2);
    shouldBeClear(x+w+2, y+h+2);
}
function shouldBeGreen(x, y) {
    d = ctx.getImageData(x, y, 1, 1).data;
    shouldBe("d[0]", "0");
    shouldBe("d[1]", "255");
    shouldBe("d[2]", "0");
    shouldBe("d[3]", "255");
}
function shouldBeClear(x, y) {
    // should be transparent black pixels
    d = ctx.getImageData(x, y, 1, 1).data;
    shouldBe("d[0]", "0");
    shouldBe("d[1]", "0");
    shouldBe("d[2]", "0");
    shouldBe("d[3]", "0");
}
function shouldNotBeCalled() {
    testFailed("Promise was rejected.");
    finishJSTest();
}
function clearContext(context) {
    context.clearRect(0, 0, 50, 50);
}

var image;
var imageWidth = 20;
var imageHeight = 20;

var aCanvas = document.createElement("canvas");
aCanvas.width = imageWidth;
aCanvas.height = imageHeight;
var aCtx = aCanvas.getContext("2d", {willReadFrequently: true});
aCtx.fillStyle = 'rgb(0, 255, 0)';
aCtx.fillRect(0, 0, 20, 20);

var canvas = document.createElement("canvas");
canvas.setAttribute("width", "50");
canvas.setAttribute("height", "50");
var ctx = canvas.getContext("2d", {willReadFrequently: true});

image = new Image();
image.onload = imageLoaded;
image.src = aCanvas.toDataURL();

function imageLoaded() {
    var bitmapFromImage, bitmapFromCanvas;
    var p1 = createImageBitmap(image, -10, -10, 20, 20).then(function(imageBitmap) { bitmapFromImage = imageBitmap });
    var p2 = createImageBitmap(aCanvas, 10, 10, 20, 20).then(function(imageBitmap) { bitmapFromCanvas = imageBitmap });
    Promise.all([p1, p2]).then(function() {
        checkBitmaps(bitmapFromImage, bitmapFromCanvas);
    }, shouldNotBeCalled);
}

function checkBitmaps(bitmapFromImage, bitmapFromCanvas) {
    var funcs = [];
    var p1 = createImageBitmap(bitmapFromImage).then(function(imageBitmap) {
        funcs[0] = checkDrawnToRect(imageBitmap, 10, 10, 10, 10);
    });
    var p2 = createImageBitmap(bitmapFromImage, -10, -10, 30, 30).then(function(imageBitmap) {
        funcs[1] = checkDrawnToRect(imageBitmap, 20, 20, 10, 10);
    });
    var p3 = createImageBitmap(bitmapFromImage, 5, 5, 20, 20).then(function(imageBitmap) {
        funcs[2] = checkDrawnToRect(imageBitmap, 5, 5, 10, 10);
    });
    var p4 = createImageBitmap(bitmapFromCanvas).then(function(imageBitmap) {
        funcs[3] = checkDrawnToRect(imageBitmap, 0, 0, 10, 10);
    });
    var p5 = createImageBitmap(bitmapFromCanvas, -15, -10, 35, 40).then(function(imageBitmap) {
        funcs[4] = checkDrawnToRect(imageBitmap, 15, 10, 10, 10);
    });
    var p6 = createImageBitmap(bitmapFromCanvas, 5, 5, 10, 10).then(function(imageBitmap) {
        funcs[5] = checkDrawnToRect(imageBitmap, 0, 0, 5, 5);
    });
    Promise.all([p1, p2, p3, p4, p5, p6]).then(function() {
        for (var i = 0; i < funcs.length; ++i)
            funcs[i]();
        finishJSTest();
    }, shouldNotBeCalled);
}

function checkDrawnToRect(bitmap, x, y, w, h) {
    // x, y, w, h are the expected location of the green square
    var imageBitmap = bitmap;
    var x1 = x;
    var y1 = y;
    var w1 = w;
    var h1 = h;
    return function() {
        clearContext(ctx);
        ctx.drawImage(imageBitmap, 0, 0);
        shouldBeFilled(x1, y1, w1, h1);

        clearContext(ctx);
        ctx.drawImage(imageBitmap, 10, 10, 40, 40);
        // scale up w and h as necessary
        var w2 = w1 * 40.0 / imageBitmap.width;
        var h2 = h1 * 40.0 / imageBitmap.height;
        // x and y are transformed
        var x2 = x1 * w2 / w1 + 10;
        var y2 = y1 * h2 / h1 + 10;
        shouldBeFilled(x2, y2, w2, h2);

        clearContext(ctx);
        ctx.drawImage(imageBitmap, 0, 0, 50, 50);
        // scale up w and h as necessary
        var w3 = w1 * 50.0 / imageBitmap.width;
        var h3 = h1 * 50.0 / imageBitmap.height;
        // x and y are transformed
        var x3 = x1 * w3 / w1;
        var y3 = y1 * h3 / h1;
        shouldBeFilled(x3, y3, w3, h3);

        clearContext(ctx);
        ctx.imageSmoothingEnabled=false;
        ctx.drawImage(imageBitmap, x1, y1, w1, h1, 0, 0, 50, 50);
        shouldBeFilled(0, 0, 50, 50);
    }
}

</script>
</body>
</html>