<html> 
  <head> 
    <title>A canvas globalCompositeOperation example</title> 
    <meta name="DC.creator" content="Kamiel Martinet, http://www.martinet.nl/"> 
    <meta name="DC.publisher" content="Mozilla Developer Center, http://developer.mozilla.org"> 
    <script type="application/x-javascript"> 
      if (window.testRunner)
	    testRunner.dumpAsText(true);

      // This test should show a table of canvas elements. The canvas elements have transforms
      // applied, and onto the background a blue square is drawn, either fully opaque or with some
      // transparency.

      // Then clip is added, which with the transform taken into account only allows drawing into
      // the bottom of the canvas.

      // Then either a green rectangle or a green ellipse is drawn, either fully opaque or with
      // some transparency. These are drawn with a different compositing mode for every row.

      // In each cell the top half should be same from one row to the next as changes here are
      // clipped out.

      // In each row the green rectangle or ellipse should be drawn with the appropriate compositing
      // mode, as per the HTML5 canvas spec.

      // In each cell the drawing should be contained within the cell boundary.

      // 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','darker','copy','xor'
      ];
      // These map to the columns of the table
      var testNames = [
        'solid rect on solid', 'alpha rect on solid', 'solid rect on alpha',
        'alpha rect on alpha', 'solid path on solid', 'alpha path on solid',
        'solid path on alpha', 'alpha path on alpha',
      ];
      function createOutputTable() {
        var tableEl = document.getElementById('outputtable');
        var row = tableEl.insertRow(-1);
        var cell = row.insertCell(-1);
        var label;
        var canvas;
        for (var i = 0; i < compositeTypes.length; i++) {
          row = tableEl.insertRow(-1);
          for (var j = 0; j < testNames.length; j++) {
            canvas = document.createElement('canvas');
            canvas.width = 65;
            canvas.height = 45;
            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, alpha) {
        context.translate(40, 0);
        context.rotate(Math.PI / 2);
        context.scale(0.2, 0.4);
        context.translate(-1000, -2000);
        if (alpha) {
          context.fillStyle = 'rgba(00,100,255,0.5)';
        } else {
          context.fillStyle = 'rgba(00,100,255,1)';
        } 
        context.fillRect(1020, 2010, 160, 80);
        context.beginPath();
        context.moveTo(1100, 1900);
        context.lineTo(1500, 1900);
        context.lineTo(1500, 2200);
        context.lineTo(1100, 2200);
        context.clip();
      }
      function doFill(context, compositeIndex, alpha, path) {
        context.globalCompositeOperation = compositeTypes[compositeIndex];
        if (alpha) {
          context.fillStyle = 'rgba(64,255,0,0.5)';
        } else {
          context.fillStyle = 'rgba(64,255,0,1)';
        } 
        if (path) {
          context.beginPath();
          context.arc(1100, 2000, 50  , 0, Math.PI*2, true);
          context.fill();
        } else {
          context.fillRect(1040, 1950, 120, 100);
        }
      }
      function draw() {
        createOutputTable();
        for (var i = 0; i < compositeTypes.length; i++) {
          for (var j = 0; j < testNames.length; j++) {
            var context = getContext(i, j);
            setupContext(context, j % 4 > 1);
            doFill(context, i, j % 2, j > 3);
          }
        }
      }
    </script> 
    <style type="text/css"> 
      body { margin: 5px; font-family: arial,verdana,helvetica; background: #fff;}
      canvas { border: 1px solid #999; }
      td { margin: 0px; padding: 0px; }
      table { border-collapse: collapse; }
    </style> 
  </head> 
  <body onload="draw();"> 
    <div> 
      <table id='outputtable'>
      </table>
    </div> 
  </body> 
</html>
