chromium/third_party/blink/web_tests/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource.html

<!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' />
    </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>