| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <canvas id="canvas" width="100" height="100"></canvas><br/> |
| <script> |
| |
| function fillRect(imageData, x, y, width, height, r, g, b, a) |
| { |
| var bytesPerRow = imageData.width * 4; |
| var data =imageData.data; |
| for (var i = 0; i < height; i++) { |
| var rowOrigin = (y+i) * bytesPerRow; |
| rowOrigin += x * 4; |
| for (var j = 0; j < width; j++) { |
| var position = rowOrigin + j * 4; |
| data[position + 0] = r; |
| data[position + 1] = g; |
| data[position + 2] = b; |
| data[position + 3] = a; |
| } |
| } |
| } |
| |
| var canvas = document.getElementById("canvas"); |
| var context = canvas.getContext("2d"); |
| |
| if (!context.createImageData) |
| context.createImageData = function(w, h) { |
| var data = this.getImageData(0, 0, w, h); |
| for (var i = 0; i < data.data.length; i++) |
| data.data[i] = 0; |
| } |
| |
| var buffer = context.createImageData(100, 100); |
| // Fill top left corner |
| fillRect(buffer, 0, 0, 50, 50, 0, 128, 0, 255); |
| |
| function checkPixelColor(x, y, color) |
| { |
| data = context.getImageData(x, y, 1, 1).data; |
| for (i = 0; i < 4; i++) |
| if (data[i] != color [i]) |
| return false; |
| return true; |
| } |
| |
| function pixelShouldBe(x, y, color) |
| { |
| assert_array_equals(context.getImageData(x, y, 1, 1).data, color); |
| } |
| |
| var pixelTests = [ |
| // 0 - 6 |
| ['PixelTestBasicDrawing 1', 25, 25, [0, 128, 0, 255]], |
| ['PixelTestBasicDrawing 2', 49, 0, [0, 128, 0, 255]], |
| ['PixelTestBasicDrawing 3', 0, 49, [0, 128, 0, 255]], |
| ['PixelTestBasicDrawing 4', 49, 49, [0, 128, 0, 255]], |
| ['PixelTestBasicDrawing 5', 50, 0, [0, 0, 0, 0]], |
| ['PixelTestBasicDrawing 6', 0, 50, [0, 0, 0, 0]], |
| ['PixelTestBasicDrawing 7', 50, 50, [0, 0, 0, 0]], |
| // 7 - 11 |
| ['PixelTestPositionedDrawing 1', 0, 50, [0, 128, 0, 255]], |
| ['PixelTestPositionedDrawing 2', 25, 75, [0, 128, 0, 255]], |
| ['PixelTestPositionedDrawing 3', 49, 50, [0, 128, 0, 255]], |
| ['PixelTestPositionedDrawing 4', 0, 99, [0, 128, 0, 255]], |
| ['PixelTestPositionedDrawing 5', 49, 99, [0, 128, 0, 255]], |
| // 12 - 15 |
| ['PixelTestTranslation 1', 50, 50, [0, 128, 0, 255]], |
| ['PixelTestTranslation 2', 75, 75, [0, 128, 0, 255]], |
| ['PixelTestTranslation 3', 99, 99, [0, 128, 0, 255]], |
| ['PixelTestTranslation 4', 50, 49, [0, 0, 0, 0]], |
| // 16 - 27 |
| ['PixelTestRegionIntersectLeftEdge 1', 0, 25, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectLeftEdge 2', 0, 50, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectLeftEdge 3', 0, 75, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectRightEdge 1', 99, 25, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectRightEdge 2', 99, 50, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectRightEdge 3', 99, 75, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectTopEdge 1', 25, 0, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectTopEdge 2', 50, 0, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectTopEdge 3', 75, 0, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectBototmEdge 1', 25, 99, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectBototmEdge 2', 50, 99, [0, 128, 0, 255]], |
| ['PixelTestRegionIntersectBototmEdge 3', 75, 99, [0, 128, 0, 255]], |
| // 28 - 51 |
| ['PixelTestDirtyRegionIntersectLeftEdge 1', 0, 25, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectLeftEdge 2', 0, 50, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectLeftEdge 3', 0, 75, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectLeftEdge 4', 10, 25, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectLeftEdge 5', 10, 50, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectLeftEdge 6', 10, 75, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectRightEdge 1', 99, 25, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectRightEdge 2', 99, 50, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectRightEdge 3', 99, 75, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectRightEdge 4', 89, 25, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectRightEdge 5', 89, 50, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectRightEdge 6', 89, 75, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectTopEdge 1', 25, 0, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectTopEdge 2', 50, 0, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectTopEdge 3', 75, 0, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectTopEdge 4', 25, 10, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectTopEdge 5', 50, 10, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectTopEdge 6', 75, 10, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectBottomEdge 1', 25, 99, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectBottomEdge 2', 50, 99, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectBottomEdge 3', 75, 99, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectBottomEdge 4', 25, 89, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectBottomEdge 5', 50, 89, [0, 128, 0, 255]], |
| ['PixelTestDirtyRegionIntersectBottomEdge 6', 75, 89, [0, 128, 0, 255]], |
| ]; |
| |
| // Test basic drawing |
| context.putImageData(buffer, 0, 0); |
| generate_tests(pixelShouldBe, pixelTests.slice(0,7)); |
| |
| // Test positioned drawing -- make bottom right green |
| context.putImageData(buffer, 0, 50); |
| generate_tests(pixelShouldBe, pixelTests.slice(7, 12)); |
| |
| // Test translation doesn't effect putImageData |
| context.translate(50, -50); |
| context.putImageData(buffer, 50, 50); |
| generate_tests(pixelShouldBe, pixelTests.slice(12, 16)); |
| context.translate(-50, 50); |
| |
| test(function(t) { |
| buffer = context.createImageData(50, 50); |
| fillRect(buffer, 0, 0, 50, 50, 0, 128, 0, 255); |
| context.putImageData(buffer, 50, 0); |
| fillRect(buffer, 0, 0, 50, 50, 255, 0, 0, 255); |
| context.putImageData(buffer, 50, 0, 15, 15, 20, 20); |
| context.fillStyle="rgb(0, 128, 0)"; |
| context.fillRect(65, 15, 20, 20); |
| var points = [0, 5, 15, 25, 35, 45]; |
| var testPassed = true; |
| outerLoop: |
| for (var x = 0; x < points.length; x++) |
| for (var y = 0; y < points.length; y++) |
| if (!checkPixelColor(points[x] + 50, points[y], [0, 128, 0, 255])) { |
| testPassed = false; |
| break outerLoop; |
| } |
| assert_true(testPassed); |
| }, "Test dirty rect handling."); |
| |
| test(function(t){ |
| fillRect(buffer, 0, 0, 50, 50, 255, 0, 0, 255); |
| context.putImageData(buffer, -50, 0); |
| pixelShouldBe(0, 25, [0, 128, 0, 255]); |
| context.putImageData(buffer, 100, 0); |
| pixelShouldBe(99, 25, [0, 128, 0, 255]); |
| context.putImageData(buffer, 0, -50); |
| pixelShouldBe(25, 0, [0, 128, 0, 255]); |
| context.putImageData(buffer, 0, 100); |
| pixelShouldBe(25, 99, [0, 128, 0, 255]); |
| }, "Test drawing outside the canvas border."); |
| |
| test(function(t){ |
| context.putImageData(buffer, 50, 0, 50, 0, 100, 100); |
| context.putImageData(buffer, 50, 0, -50, 0, 50, 100); |
| context.putImageData(buffer, 50, 0, 0, 50, 100, 100); |
| context.putImageData(buffer, 50, 0, 50, -50, 100, 100); |
| var points = [0, 5, 15, 25, 35, 45]; |
| var testPassed = true; |
| outerLoop: |
| for (var x = 0; x < points.length; x++) |
| for (var y = 0; y < points.length; y++) |
| if (!checkPixelColor(points[x] + 50, points[y], [0, 128, 0, 255])) { |
| testPassed = false; |
| break outerLoop; |
| } |
| assert_true(testPassed); |
| }, "test drawing with non-intersecting dirty rect."); |
| |
| test(function(t) { |
| buffer = context.createImageData(100, 100); |
| fillRect(buffer, 0, 0, 100, 100, 0, 128, 0, 255); |
| fillRect(buffer, 10, 10, 80, 80, 255, 0, 0, 255); |
| //left edge |
| context.putImageData(buffer, -90, 0); |
| generate_tests(pixelShouldBe, pixelTests.slice(16, 19)); |
| //right edge |
| context.putImageData(buffer, 90, 0); |
| generate_tests(pixelShouldBe, pixelTests.slice(19, 22)); |
| //top edge |
| context.putImageData(buffer, 0, -90); |
| generate_tests(pixelShouldBe, pixelTests.slice(22, 25)); |
| //bottom edge |
| context.putImageData(buffer, 0, 90); |
| generate_tests(pixelShouldBe, pixelTests.slice(25, 28)); |
| }, "Test drawing to region intersect edge of canvas."); |
| |
| test(function(t) { |
| // left edge |
| context.putImageData(buffer, 0, 0, -90, 0, 100, 100); |
| generate_tests(pixelShouldBe, pixelTests.slice(28, 34)); |
| //right edge |
| context.putImageData(buffer, 0, 0, 90, 0, 100, 100); |
| generate_tests(pixelShouldBe, pixelTests.slice(34, 40)); |
| // top edge |
| context.putImageData(buffer, 0, 0, 0, -90, 100, 100); |
| generate_tests(pixelShouldBe, pixelTests.slice(40, 46)); |
| //bottom edge |
| context.putImageData(buffer, 0, 0, 0, 90, 100, 100); |
| generate_tests(pixelShouldBe, pixelTests.slice(46)); |
| }, "Test drawing with only part of the dirty region intersecting the window."); |
| |
| test(function(t) { |
| var smallbuffer = context.createImageData(10, 10); |
| fillRect(smallbuffer, 0, 0, 10, 10, 255, 0, 0, 255); |
| context.putImageData(smallbuffer, 1.5, 1); |
| pixelShouldBe(11, 11, [0, 128, 0, 255]); |
| fillRect(smallbuffer, 0, 0, 10, 10, 0, 128, 0, 255); |
| context.putImageData(smallbuffer, 1.5, 1); |
| pixelShouldBe(1, 1, [0, 128, 0, 255]); |
| }, "Test clamping of dx/dy."); |
| |
| test(function(t) { |
| var smallbuffer = context.createImageData(10, 10); |
| fillRect(smallbuffer, 0, 0, 10, 10, 0, 128, 0, 255); |
| context.fillStyle = "red"; |
| context.fillRect(1, 1, 9, 9); |
| context.putImageData(smallbuffer, 1, 1, 0.5, 0.5, 8.5, 8.5); |
| pixelShouldBe(1, 1, [0, 128, 0, 255]); |
| pixelShouldBe(10, 10, [0, 128, 0, 255]); |
| context.fillRect(1, 1, 9, 9); |
| context.putImageData(smallbuffer, 1, 1, 0.25, 0.25, 9, 9); |
| pixelShouldBe(1, 1, [0, 128, 0, 255]); |
| pixelShouldBe(10, 10, [0, 128, 0, 255]); |
| context.fillRect(1, 1, 8, 8); |
| context.putImageData(smallbuffer, 1, 1, 0.0, 0.0, 8.5, 8.5); |
| pixelShouldBe(1, 1, [0, 128, 0, 255]); |
| pixelShouldBe(9, 9, [0, 128, 0, 255]); |
| context.fillRect(1, 1, 8, 8); |
| context.putImageData(smallbuffer, 1, 1, 0.0, 0.0, 8.25, 8.25); |
| pixelShouldBe(1, 1, [0, 128, 0, 255]); |
| pixelShouldBe(9, 9, [0, 128, 0, 255]); |
| context.fillRect(1, 1, 7, 7); |
| context.putImageData(smallbuffer, 1, 1, 0.5, 0.5, 7.9, 7.9); |
| pixelShouldBe(1, 1, [0, 128, 0, 255]); |
| pixelShouldBe(9, 9, [0, 128, 0, 255]); |
| }, "Test clamping of dirtyX/Y/Width/Height."); |
| |
| var testInvalidParams = [ |
| ['TestInvalidParam 1', TypeError, function() {context.putImageData({}, 0, 0);}], |
| ['TestInvalidParam 2', TypeError, function() {context.putImageData(null, 0, 0, 0, 0, 0, 0);}], |
| ['TestInvalidParam 3', TypeError, function() {context.putImageData(undefined, 0, 0, 0, 0, 0, 0);}], |
| |
| ]; |
| |
| generate_tests(assert_throws_js, testInvalidParams); |
| |
| test(function(t) { |
| var smallbuffer = context.createImageData(10, 10); |
| var rectcanvas = document.createElement("canvas"); |
| rectcanvas.width = 20; |
| rectcanvas.height = 10; |
| var rectbuffer = rectcanvas.getContext("2d"); |
| rectbuffer.putImageData(smallbuffer, 10, 0); |
| |
| var rectcanvas = document.createElement("canvas"); |
| rectcanvas.width = 10; |
| rectcanvas.height = 20; |
| var rectbuffer = rectcanvas.getContext("2d"); |
| rectbuffer.putImageData(smallbuffer, 0, 10); |
| }, "Ensure we don't mess up bounds clipping checks."); |
| </script> |