| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <canvas id="dest" height="100" width="100"></canvas> |
| |
| <script> |
| var sourceCanvasWidth = sourceCanvasHeight = 50; |
| var destCanvasWidth = destCanvasHeight = 100; |
| var blueRect = {x: 0, y: 0, w: 50, h: 50}; |
| var blackRect = {x: 5, y: 5, w: 40, h: 40}; |
| var redPixel = [255, 0, 0, 255]; |
| var bluePixel = [0, 0, 255, 255]; |
| var blackPixel = [0, 0, 0, 255]; |
| var transparentBlackPixel = [0, 0, 0, 0]; |
| |
| var destCanvas = document.getElementById('dest'); |
| var destCtx = destCanvas.getContext('2d'); |
| destCtx.imageSmoothingEnabled = false; |
| |
| function checkPixel(location, expected) { |
| var actual = destCtx.getImageData(location[0], location[1], 1, 1).data; |
| assert_array_equals(actual, expected); |
| } |
| |
| function PreparePixelTests(blueCheck, blackCheck, redCheck, testDescription) { |
| var pixelTests = []; |
| for (var i = 0; i < blueCheck.length; i++) { |
| var message = testDescription + 'Pixel ' + blueCheck[i][0] + ',' + blueCheck[i][1] + ' should be blue.'; |
| pixelTests.push([message, blueCheck[i], bluePixel]); |
| } |
| for (var i = 0; i < blackCheck.length; i++) { |
| var message = testDescription + 'Pixel ' + blackCheck[i][0] + ',' + blackCheck[i][1] + ' should be black.'; |
| pixelTests.push([message, blackCheck[i], blackPixel]); |
| } |
| for (var i = 0; i < redCheck.length; i++) { |
| var message = testDescription + 'Pixel ' + redCheck[i][0] + ',' + redCheck[i][1] + ' should be red.'; |
| pixelTests.push([message, redCheck[i], redPixel]); |
| } |
| pixelTests.push([testDescription + 'Pixel outside canvas should be transparent black.\n', [100, 100], transparentBlackPixel]); |
| return pixelTests; |
| } |
| |
| function drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription) { |
| destCtx.fillStyle = 'red'; |
| destCtx.fillRect(0, 0, destCanvasWidth, destCanvasHeight); |
| |
| var sourceCanvas = document.createElement('canvas'); |
| sourceCanvas.width = sourceCanvasWidth; |
| sourceCanvas.height = sourceCanvasHeight; |
| var sourceCtx = sourceCanvas.getContext('2d'); |
| sourceCtx.fillStyle = 'blue'; |
| sourceCtx.fillRect(blueRect.x, blueRect.y, blueRect.w, blueRect.h); |
| sourceCtx.fillStyle = 'black'; |
| sourceCtx.fillRect(blackRect.x, blackRect.y, blackRect.w, blackRect.h); |
| if (typeof sourceRect.x !== 'undefined') |
| destCtx.drawImage(sourceCanvas, sourceRect.x, sourceRect.y, sourceRect.w, sourceRect.h, |
| destRect.x, destRect.y, destRect.w, destRect.h); |
| else if (typeof destRect.w !== 'undefined') |
| destCtx.drawImage(sourceCanvas, destRect.x, destRect.y, destRect.w, destRect.h); |
| else |
| destCtx.drawImage(sourceCanvas, destRect.x, destRect.y); |
| var pixelTests = PreparePixelTests(blueCheck, blackCheck, redCheck, testDescription); |
| generate_tests(checkPixel, pixelTests); |
| } |
| |
| var testDescription; |
| var sourceRect = {}, destRect = {}; |
| var blueCheck, blackCheck, redCheck; |
| |
| // 2 arguments, the dest origin is 0,0 |
| // The source canvas will be copied to the 0,0 position of the destination canvas |
| testDescription = 'Test scenario 1: dx = 0, dy = 0 --- '; |
| destRect = {x: 0, y: 0}; |
| blueCheck = [[0,0], [0,49], [49,0], [49,49]]; |
| blackCheck = [[5,5], [5,44], [44,5], [44,44]]; |
| redCheck = [[50,0], [0,50], [50,50], [99,99]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // 2 arguments, the dest origin is not 0,0 |
| // The source canvas will copied to the 25, 25 position of the destination canvas |
| testDescription = 'Test scenario 2: dx = 25, dy = 25 --- '; |
| destRect = {x: 25, y: 25}; |
| blueCheck = [[25,25], [25,74], [74,25], [74,74]]; |
| blackCheck = [[30,30], [30,69], [69,30], [69,69]]; |
| redCheck = [[24,24], [24,75], [75,24], [75,75]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // 4 arguments, the source origin is not 0,0, the dest size is provided |
| // The source canvas will copied to the 50, 50 position of the destination canvas and |
| // on an area of 50x50 pixels |
| testDescription = 'Test scenario 3: dx = 50, dy = 50, dw = 50, dh = 50 --- '; |
| destRect = {x: 50, y: 50, w: 50, h: 50}; |
| blueCheck = [[50,50], [50,99], [99,50], [99,99]]; |
| blackCheck = [[55,55], [55,94], [94,55], [94,94]]; |
| redCheck = [[0,0], [49,49], [49,99], [99,49]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // 4 arguments, the dest origin is not 0,0 and the dest size is provided but |
| // does not match the size of the source. The image will be distorted |
| // The source canvas will copied to the 50,50 position of the destination canvas |
| // and it will be shrunk to a and area of 20x20 |
| testDescription = 'Test scenario 4: dx = 50, dy = 50, dw = 20, dh = 20 --- '; |
| destRect = {x: 50, y: 50, w: 20, h: 20}; |
| blueCheck = [[50,50], [50,69], [69,50], [69,69]]; |
| blackCheck = [[52,52], [52,67], [67,52], [67,67]]; |
| redCheck = [[49,49], [49,70], [70,49], [70,70]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // The source canvas will copied to the 50,50 position of the destination canvas |
| // over an area of 50x25 pixels |
| // The copied image will be distorted along the x axis |
| testDescription = 'Test scenario 5: dx = 50, dy = 50, dw = 50, dh = 20 --- '; |
| destRect = {x: 50, y: 50, w: 50, h: 20}; |
| blueCheck = [[50,50], [50,69], [99,50], [99,69]]; |
| blackCheck = [[55,52], [55,67], [94,52], [94,67]]; |
| redCheck = [[49,49], [49, 69], [99,49], [99,70]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // 8 arguments, both destination and source origins are 0, 0 |
| // An area of 25x25 pixels of the source image will be copied to |
| // an area of 25x25 pixels of the destination canvas |
| // destCtx.drawImage(sourceCanvas, 0, 0, 25, 25, 0, 0, 25, 25); |
| testDescription = 'Test scenario 6: sx = 0, sy = 0, sw = 25, sh = 25, dx = 0, dy = 0, dw = 25, dh = 25 --- '; |
| sourceRect = {x: 0, y: 0, w: 25, h: 25}; |
| destRect = {x: 0, y: 0, w: 25, h: 25}; |
| blueCheck = [[0,0], [4,4], [0,24], [24,0]]; |
| blackCheck = [[5,5], [5,24], [24,5], [24,24]]; |
| redCheck = [[25,25], [25, 99], [99,25], [99,99]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // 8 arguments the destination origin is not 0,0 |
| // An area of 25x25 pixels of the source image will be copied to |
| // an area of 25x25 pixels of the destination canvas in the position 25,25 |
| testDescription = 'Test scenario 7: sx = 0, sy = 0, sw = 25, sh = 25, dx = 25, dy = 25, dw = 25, dh = 25 --- '; |
| sourceRect = {x: 0, y: 0, w: 25, h: 25}; |
| destRect = {x: 25, y: 25, w: 25, h: 25}; |
| blueCheck = [[25,25], [25,49], [49,25], [29,29]]; |
| blackCheck = [[30,30], [30,49], [49,30], [49,49]]; |
| redCheck = [[24,24], [24, 50], [50,24], [50,50]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // The source rectangle overflows the source image |
| // The source area is clipped to fit the source image |
| // and the destination are is clipped in the same proportion |
| testDescription = 'Test scenario 8: sx = 25, sy = 25, sw = 50, sh = 50, dx = 0, dy = 0, dw = 50, dh = 50 --- '; |
| sourceRect = {x: 25, y: 25, w: 50, h: 50}; |
| destRect = {x: 0, y: 0, w: 50, h: 50}; |
| blueCheck = [[0,20], [20,0], [20,20], [24,24]]; |
| blackCheck = [[0,0], [0,19], [19,0], [19,19]]; |
| redCheck = [[0,25], [25, 0], [25,25], [99,99]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // The destination rectangle has negative width and height. When the source |
| // rectangle is outside the source image, the source rectangle must be clipped |
| // to the source image and the destination rectangle must be clipped in the same |
| // proportion. |
| testDescription = 'Test scenario 9: sx = 0, sy = 0, sw = 50, sh = 50, dx = 100, dy = 100, dw = -50, dh = -50 --- '; |
| sourceRect = {x: 0, y: 0, w: 50, h: 50}; |
| destRect = {x: 100, y: 100, w: -50, h: -50}; |
| blueCheck = [[50,50], [50,99], [99,50], [99,99]]; |
| blackCheck = [[55,55], [55,94], [94,55], [94,94]]; |
| redCheck = [[0,0], [49,49], [0,99], [99,0]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // The destination rectangle is larger than the destination canvas |
| // When the destination rectangle is outside the destination image (the scratch bitmap), |
| // the pixels that land outside the scratch bitmap are discarded, |
| // as if the destination was an infinite canvas whose rendering was |
| // clipped to the dimensions of the scratch bitmap. |
| testDescription = 'Test scenario 10: sx = 0, sy = 0, sw = 50, sh = 50, dx = 0, dy = 0, dw = 200, dh = 200 --- '; |
| sourceRect = {x: 0, y: 0, w: 50, h: 50}; |
| destRect = {x: 0, y: 0, w: 200, h: 200}; |
| blueCheck = [[0,0], [0,99], [99,0], [19,19]]; |
| blackCheck = [[20,20], [20,99], [99,20], [99,99]]; |
| redCheck = []; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // The source rectangle is larger than the source canvas |
| // The source area is clipped to fit the source image |
| // and the destination are is clipped in the same proportion |
| testDescription = 'Test scenario 11: sx = 0, sy = 0, sw = 100, sh = 100, dx = 0, dy = 0, dw = 50, dh = 50 --- '; |
| sourceRect = {x: 0, y: 0, w: 100, h: 100}; |
| destRect = {x: 0, y: 0, w: 50, h: 50}; |
| blueCheck = [[0,0], [1,1], [23,23], [24,24]]; |
| blackCheck = [[3,3], [3,21], [21,3], [21,21]]; |
| redCheck = [[0,25], [25, 0], [25,25], [99,99]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| // Negative coordinates of the source rectangle. |
| // The source area is clipped to fit the source image and the destination area |
| // is clipped in the same proportion. In this specific test: |
| // - source is clipped by 20 from top and left. |
| // - destination will get proportionally clipped by 50 from top and left as we |
| // are scaling the source image 2.5 times. |
| // - the rect will be drawn from 70,70 to 100,100. |
| testDescription = 'Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- '; |
| sourceRect = {x: -20, y: -20, w: 50, h: 50}; |
| destRect = {x: 20, y: 20, w: 125, h: 125}; |
| blueCheck = [[70,70], [70,99], [99,70], [82,82]]; |
| blackCheck = [[84,84], [84,99], [99,84], [99,99]]; |
| redCheck = [[0,69], [69, 0], [69,69]]; |
| drawCanvasOnCanvasUsingDrawImage(sourceRect, destRect, blueCheck, blackCheck, redCheck, testDescription); |
| |
| </script> |