| <!doctype html> |
| <html> |
| <head> |
| <title>Check repaint region of fillRect() and drawImage() with different composite modes.</title> |
| <style type="text/css"> |
| body { margin: 5px; font-family: arial,verdana,helvetica; background: #fff; } |
| canvas { border: 1px solid #999; } |
| div { margin: 10px; } |
| #output h1 { font-size: medium; font-weight: normal; } |
| #output h2 { font-size: small; font-weight: normal; } |
| #output div { font-size: small; margin: 0px; } |
| #output .pass { color: green; } |
| #output .fail { color: rgb(255, 0, 0); } |
| #output .error { color: rgb(255, 0, 64); } |
| td { padding: 2px 5px; } |
| table { border-collapse: collapse; } |
| </style> |
| </head> |
| <body> |
| <div>Test Results</div> |
| <div><table id='outputtable'></table></div> |
| <div>Test Image</div> |
| <div><img id = "image" src="data:image/png;base64, |
| iVBORw0KGgoAAAANSUhEUgAAAJYAAAA8CAIAAAAL5NQ9AAAACXBIWXMAAAsTAAALEwEAmpwY |
| AAAAB3RJTUUH2woaBQc4oLEFpAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeB |
| DhcAAACMSURBVHja7dNBEYAgFEVRPhHMYgAzUIsmVnFvB/fsoQb+ObfBmzMvxneW1D1vzz2w |
| FiEUQiFEKIRCKIQIhVAIhRChEAqhECIUQiEUQoRCKIRCiFAIhVAIEep3xTWTLzzu5oVCKIRC |
| iFAIhVAIEQqhEAohQiEUQiFEKIRCKIQIhVAIhRChEAqhECLUZi3VEwcBMGr1NgAAAABJRU5E |
| rkJggg== |
| "></div> |
| <div>Test Canvas</div> |
| <div><canvas id = "source-canvas"></canvas></div> |
| <div>Test Video</div> |
| <div><video id="video"> |
| <source src="../../../fast/canvas/resources/canvas_video.webm" type='video/webm' /> |
| <source src="../../../fast/canvas/resources/canvas_video.mp4" type='video/mp4' /> |
| <source src="../../../fast/canvas/resources/canvas_video.ogv" type='video/ogg' /> |
| </video></div> |
| <script src="../resources/text-based-repaint.js"></script> |
| <script type="application/x-javascript"> |
| // These map to the rows of the table |
| var compositeTypes = [ |
| 'source-over','source-in','source-out','source-atop', |
| 'destination-over','destination-in','destination-out','destination-atop', |
| 'lighter','copy','xor' |
| ]; |
| |
| // These map to the columns of the table |
| var testNames = [ |
| 'solid color', 'image', 'canvas', 'video' |
| ]; |
| |
| function createOutputTable() { |
| var tableEl = document.getElementById('outputtable'); |
| var row = tableEl.insertRow(-1); |
| var cell = row.insertCell(-1); |
| var label; |
| for (var j = 0; j < testNames.length; j++) { |
| cell = row.insertCell(-1); |
| label = document.createTextNode(testNames[j]); |
| cell.appendChild(label); |
| } |
| for (var i = 0; i < compositeTypes.length; i++) { |
| row = tableEl.insertRow(-1); |
| cell = row.insertCell(-1); |
| label = document.createTextNode(compositeTypes[i]); |
| cell.appendChild(label); |
| for (var j = 0; j < testNames.length; j++) { |
| var canvas = document.createElement('canvas'); |
| canvas.width = 130; |
| canvas.height = 40; |
| canvas.id = compositeTypes[i] + testNames[j]; |
| cell = row.insertCell(-1); |
| cell.appendChild(canvas); |
| } |
| } |
| } |
| |
| function getContext(compositeIndex, testIndex) { |
| var id = compositeTypes[compositeIndex] + testNames[testIndex]; |
| var context = document.getElementById(id).getContext('2d'); |
| return context; |
| } |
| |
| function setupContext(context) { |
| context.fillStyle = 'blue'; |
| context.fillRect(5, 5, 120, 30); |
| context.beginPath(); |
| context.moveTo(0, 0); |
| context.lineTo(0, 45); |
| context.lineTo(80, 45); |
| context.lineTo(80, 0); |
| context.clip(); |
| context.translate(40, -10); |
| context.scale(0.4, 0.6); |
| context.rotate(Math.PI / 8); |
| context.translate(-10, -10); |
| } |
| |
| function prepareRepaintTest() { |
| if (window.testRunner) |
| testRunner.dumpAsText(); |
| createOutputTable(); |
| for (var i = 0; i < compositeTypes.length; i++) { |
| for (var j = 0; j < testNames.length; j++) { |
| var context = getContext(i, j); |
| context.save(); |
| setupContext(context); |
| } |
| } |
| } |
| |
| function drawRect(context) { |
| context.fillStyle = 'green'; |
| context.fillRect(10, 10, 150, 60); |
| } |
| |
| function drawImage(context) { |
| context.drawImage(document.getElementById('image'), 10, 10); |
| } |
| |
| function drawCanvas(context) { |
| context.drawImage(document.getElementById('source-canvas'), 10, 10); |
| } |
| |
| function drawVideo(context) { |
| context.drawImage(document.getElementById('video'), 10, 10); |
| } |
| |
| // callback from text-based-repaint.js |
| function repaintTest() { |
| for (var i = 0; i < compositeTypes.length; i++) { |
| for (var j = 0; j < testNames.length; j++) { |
| var context = getContext(i, j); |
| context.globalCompositeOperation = compositeTypes[i]; |
| switch (testNames[j]) { |
| case 'solid color': |
| drawRect(context); |
| break; |
| case 'image': |
| drawImage(context); |
| break; |
| case 'canvas': |
| drawCanvas(context); |
| break; |
| case 'video': |
| drawVideo(context); |
| } |
| context.restore(); |
| } |
| } |
| // Because canvas invalidations are processed at the end of the current task, |
| // the repaint test has to end in a subsequent task in order to capture the repaint. |
| setTimeout(finishRepaintTest, 0); |
| } |
| |
| // we can start this test after the video can be played. |
| function startTest() { |
| prepareRepaintTest(); |
| runRepaintTest(); |
| } |
| |
| var video = document.getElementById("video"); |
| video.addEventListener("playing", _ => { |
| // Video controls will do a re-paint when it starts playing. |
| setTimeout(startTest); |
| }, { passive: true, once: true }); |
| video.play(); |
| |
| var imageElement = document.getElementById('image'); |
| var canvas = document.getElementById('source-canvas'); |
| canvas.width = imageElement.width; |
| canvas.height = imageElement.height; |
| var context = canvas.getContext('2d'); |
| context.drawImage(imageElement, 0, 0); |
| |
| window.testIsAsync = true; |
| </script> |
| </body> |
| </html> |