forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			447 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			447 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE HTML>
 | |
| <title>Canvas Tests</title>
 | |
| <script src="/tests/SimpleTest/SimpleTest.js"></script>
 | |
| <link rel="stylesheet" href="/tests/SimpleTest/test.css">
 | |
| <body>
 | |
| <script>
 | |
| 
 | |
| SimpleTest.waitForExplicitFinish();
 | |
| const Cc = SpecialPowers.Cc;
 | |
| const Cr = SpecialPowers.Cr;
 | |
| 
 | |
| function isPixel(ctx, x,y, c, d) {
 | |
|   var pos = x + "," + y;
 | |
|   var color = c[0] + "," + c[1] + "," + c[2] + "," + c[3];
 | |
|     var pixel = ctx.getImageData(x, y, 1, 1);
 | |
|     var pr = pixel.data[0],
 | |
|         pg = pixel.data[1],
 | |
|         pb = pixel.data[2],
 | |
|         pa = pixel.data[3];
 | |
|     ok(c[0]-d <= pr && pr <= c[0]+d &&
 | |
|        c[1]-d <= pg && pg <= c[1]+d &&
 | |
|        c[2]-d <= pb && pb <= c[2]+d &&
 | |
|        c[3]-d <= pa && pa <= c[3]+d,
 | |
|        "pixel "+pos+" of "+ctx.canvas.id+" is "+pr+","+pg+","+pb+","+pa+"; expected "+color+" +/- "+d);
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_drawClipPath_canvas</p>
 | |
| <canvas id="c1" class="output" width="100" height="100">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| function test_drawClipPath_canvas() {
 | |
|   var c = document.getElementById("c1");
 | |
|   var ctx = c.getContext("2d");
 | |
| 
 | |
|   var path = new Path2D();
 | |
|   path.rect(0, 0, 100, 100);
 | |
|   path.rect(25, 25, 50, 50);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.beginPath();
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.save();
 | |
|   ctx.clip(path);
 | |
| 
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
 | |
|   ctx.restore();
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.beginPath();
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.save();
 | |
|   ctx.clip(path, 'nonzero');
 | |
| 
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
 | |
|   ctx.restore();
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.beginPath();
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.save();
 | |
|   ctx.clip(path, 'evenodd');
 | |
| 
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   isPixel(ctx, 50, 50, [255, 0, 0, 255], 5);
 | |
|   ctx.restore();
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_drawFillPath_canvas</p>
 | |
| <canvas id="c2" class="output" width="100" height="100">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| function test_drawFillPath_canvas() {
 | |
|   var c = document.getElementById("c2");
 | |
|   var ctx = c.getContext("2d");
 | |
| 
 | |
|   var path = new Path2D();
 | |
|   path.rect(0, 0, 100, 100);
 | |
|   path.rect(25, 25, 50, 50);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.fill(path);
 | |
|   isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.fill(path, 'nonzero');
 | |
|   isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.fill(path, 'evenodd');
 | |
|   isPixel(ctx, 50, 50, [255, 0, 0, 255], 5);
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_drawStrokePath_canvas</p>
 | |
| <canvas id="c3" class="output" width="100" height="100">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| function test_drawStrokePath_canvas() {
 | |
|   var c = document.getElementById("c3");
 | |
|   var ctx = c.getContext("2d");
 | |
| 
 | |
|   var path = new Path2D();
 | |
|   path.rect(0, 0, 100, 100);
 | |
|   path.rect(25, 25, 50, 50);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.strokeStyle = 'rgb(0,255,0)';
 | |
|   ctx.lineWidth = 5;
 | |
|   ctx.stroke(path);
 | |
|   isPixel(ctx, 0, 0, [0, 255, 0, 255], 5);
 | |
|   isPixel(ctx, 25, 25, [0, 255, 0, 255], 5);
 | |
|   isPixel(ctx, 10, 10, [255, 0, 0, 255], 5);
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_large_canvas</p>
 | |
| <canvas id="c4" class="output" width="10000" height="100">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| function test_large_canvas() {
 | |
|   // test paths on large canvases. On certain platforms this will
 | |
|   // trigger retargeting of the backend
 | |
|   var c = document.getElementById("c4");
 | |
|   var ctx = c.getContext("2d");
 | |
| 
 | |
|   var path = new Path2D();
 | |
|   path.rect(0, 0, 100, 100);
 | |
|   path.rect(25, 25, 50, 50);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.fill(path);
 | |
|   isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.fill(path, 'nonzero');
 | |
|   isPixel(ctx, 50, 50, [0, 255, 0, 255], 5);
 | |
| 
 | |
|   ctx.fillStyle = 'rgb(255,0,0)';
 | |
|   ctx.fillRect(0, 0, 100, 100);
 | |
|   ctx.fillStyle = 'rgb(0,255,0)';
 | |
|   ctx.fill(path, 'evenodd');
 | |
|   isPixel(ctx, 50, 50, [255, 0, 0, 255], 5);
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_isPointInPath_canvas</p>
 | |
| <canvas id="c5" class="output" width="100" height="100">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| 
 | |
| function shouldThrow(ctx, s) {
 | |
|   var _ok = false;
 | |
|   try {
 | |
|     eval(s);
 | |
|   } catch(e) {
 | |
|     _ok = true;
 | |
|   }
 | |
|   ok(_ok, s);
 | |
| }
 | |
| 
 | |
| function shouldBeTrue(ctx, path, s) {
 | |
|   var _ok = eval(s);
 | |
|   ok(_ok, s);
 | |
| }
 | |
| function shouldBeFalse(ctx, path, s) {
 | |
|   var _ok = !eval(s);
 | |
|   ok(_ok, s);
 | |
| }
 | |
| 
 | |
| function test_isPointInPath_canvas() {
 | |
|   var c = document.getElementById("c5");
 | |
|   var ctx = c.getContext("2d");
 | |
| 
 | |
|   var path = new Path2D();
 | |
|   path.rect(0, 0, 100, 100);
 | |
|   path.rect(25, 25, 50, 50);
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInPath(path, 50, 50)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInPath(path, NaN, 50)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInPath(path, 50, NaN)");
 | |
| 
 | |
|   path = new Path2D();
 | |
|   path.rect(0, 0, 100, 100);
 | |
|   path.rect(25, 25, 50, 50);
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInPath(path, 50, 50, 'nonzero')");
 | |
| 
 | |
|   path = new Path2D();
 | |
|   path.rect(0, 0, 100, 100);
 | |
|   path.rect(25, 25, 50, 50);
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInPath(path, 50, 50, 'evenodd')");
 | |
| 
 | |
|   shouldThrow(ctx, "ctx.isPointInPath(null, 50, 50)");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath(null, 50, 50, 'nonzero')");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath(null, 50, 50, 'evenodd')");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath(path, 50, 50)");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath(path, 50, 50, 'nonzero')");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath(path, 50, 50, 'evenodd')");
 | |
| 
 | |
|   shouldThrow(ctx, "ctx.isPointInPath([], 50, 50)");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath([], 50, 50, 'nonzero')");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath([], 50, 50, 'evenodd')");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath({}, 50, 50)");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath({}, 50, 50, 'nonzero')");
 | |
|   shouldThrow(ctx, "ctx.isPointInPath({}, 50, 50, 'evenodd')");
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_isPointInStroke_canvas</p>
 | |
| <canvas id="c6" class="output" width="100" height="100">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| 
 | |
| function test_isPointInStroke_canvas() {
 | |
|   var c = document.getElementById("c6");
 | |
|   var ctx = c.getContext("2d");
 | |
| 
 | |
|   ctx.strokeStyle = '#0ff';
 | |
| 
 | |
|   var path = new Path2D();
 | |
|   path.rect(20,20,100,100);
 | |
| 
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,20,20)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,120,20)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,20,120)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,120,120)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,70,20)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,20,70)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,120,70)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,70,120)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,22,22)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,118,22)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,22,118)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,118,118)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,70,18)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,122,70)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,70,122)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,18,70)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,NaN,122)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,18,NaN)");
 | |
| 
 | |
|   shouldThrow(ctx, "ctx.isPointInStroke(null,70,20)");
 | |
|   shouldThrow(ctx, "ctx.isPointInStroke([],20,70)");
 | |
|   shouldThrow(ctx, "ctx.isPointInStroke({},120,70)");
 | |
| 
 | |
|   ctx.lineWidth = 10;
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,22,22)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,118,22)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,22,118)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,118,118)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,70,18)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,122,70)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,70,122)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,18,70)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,26,70)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,70,26)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,70,114)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,114,70)");
 | |
| 
 | |
|   path = new Path2D();
 | |
|   path.moveTo(10,10);
 | |
|   path.lineTo(110,20);
 | |
|   path.lineTo(10,30);
 | |
|   ctx.lineJoin = "bevel";
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,113,20)");
 | |
| 
 | |
|   ctx.miterLimit = 40.0;
 | |
|   ctx.lineJoin = "miter";
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,113,20)");
 | |
| 
 | |
|   ctx.miterLimit = 2.0;
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,113,20)");
 | |
| 
 | |
|   path = new Path2D();
 | |
|   path.moveTo(10,10);
 | |
|   path.lineTo(110,10);
 | |
|   ctx.lineCap = "butt";
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,112,10)");
 | |
| 
 | |
|   ctx.lineCap = "round";
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,112,10)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,117,10)");
 | |
| 
 | |
|   ctx.lineCap = "square";
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,112,10)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,117,10)");
 | |
| 
 | |
|   ctx.lineCap = "butt";
 | |
|   ctx.setLineDash([10,10]);
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,15,10)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,25,10)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,35,10)");
 | |
| 
 | |
|   ctx.lineDashOffset = 10;
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,15,10)");
 | |
|   shouldBeTrue(ctx, path, "ctx.isPointInStroke(path,25,10)");
 | |
|   shouldBeFalse(ctx, path, "ctx.isPointInStroke(path,35,10)");
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_pathconstructor_canvas</p>
 | |
| <canvas id="c7" class="output" width="200" height="100">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| 
 | |
| function test_pathconstructor_canvas() {
 | |
|   var c = document.getElementById("c7");
 | |
|   var ctx = c.getContext("2d");
 | |
| 
 | |
|   var p = new Path2D("M100,0L200,0L200,100L100,100z");
 | |
|   ctx.fillStyle = 'blue';
 | |
|   ctx.fill(p);
 | |
|   isPixel(ctx, 105, 5, [0, 0, 255, 255], 0);
 | |
|   isPixel(ctx, 5, 5, [0, 0, 0, 0], 0);
 | |
| 
 | |
|   // copy constructor. This should not crash.
 | |
|   var p1 = new Path2D();
 | |
|   var _p2 = new Path2D(p1);
 | |
|   p1.arcTo(0, 0, 1, 1, 2);
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <p>Canvas test: test_addpath_canvas</p>
 | |
| <canvas id="c8" class="output" width="200" height="200">+
 | |
| </canvas>
 | |
| <script type="text/javascript">
 | |
| 
 | |
| function test_addpath_canvas() {
 | |
|   var c = document.getElementById("c8");
 | |
|   var ctx = c.getContext("2d");
 | |
|   ctx.beginPath();
 | |
|   var p1 = new Path2D();
 | |
|   p1.rect(0,0,100,100);
 | |
|   var p2 = new Path2D();
 | |
|   p2.rect(0,100,100,100);
 | |
|   var m = ctx.currentTransform;
 | |
|   p1.addPath(p2, m);
 | |
|   ctx.fillStyle = 'yellow';
 | |
|   ctx.fill(p1);
 | |
|   isPixel(ctx, 0, 100, [255, 255, 0, 255], 0);
 | |
| 
 | |
|   ctx.clearRect(0,0,200,200);
 | |
| 
 | |
|   ctx.beginPath();
 | |
|   var p3 = new Path2D();
 | |
|   p3.rect(0,0,100,100);
 | |
|   var p4 = new Path2D();
 | |
|   p4.rect(0,100,100,100);
 | |
|   var m = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix();
 | |
|   m.a = 1; m.b = 0;
 | |
|   m.c = 0; m.d = 1;
 | |
|   m.e = 100; m.f = -100;
 | |
|   p3.addPath(p4, m);
 | |
|   ctx.fillStyle = 'yellow';
 | |
|   ctx.fill(p3);
 | |
|   isPixel(ctx, 50, 50, [255, 255, 0, 255], 0);
 | |
|   isPixel(ctx, 150, 150, [0, 0, 0, 0], 0);
 | |
| 
 | |
|   var p5 = new Path2D();
 | |
|   p5.rect(0,0,100,100);
 | |
|   shouldThrow(ctx, "p5.addPath(null, m)");
 | |
|   shouldThrow(ctx, "p5.addPath([], m)");
 | |
|   shouldThrow(ctx, "p5.addPath({}, m)");
 | |
| 
 | |
|   p5 = p5.addPath(p5);
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <script>
 | |
| 
 | |
| function runTests() {
 | |
|  try {
 | |
|   test_drawClipPath_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_drawClipPath_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  try {
 | |
|   test_drawFillPath_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_drawFillPath_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  try {
 | |
|   test_drawStrokePath_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_drawStrokePath_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  try {
 | |
|   test_large_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_large_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  try {
 | |
|   test_isPointInPath_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_isPointInPath_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  try {
 | |
|   test_isPointInStroke_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_isPointInStroke_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  try {
 | |
|   test_pathconstructor_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_pathconstructor_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  try {
 | |
|   test_addpath_canvas();
 | |
|  } catch(e) {
 | |
|   ok(false, "unexpected exception thrown in: test_addpath_canvas");
 | |
|   throw e;
 | |
|  }
 | |
|  SimpleTest.finish();
 | |
| }
 | |
| 
 | |
| addLoadEvent(function() {
 | |
|   SpecialPowers.pushPrefEnv({"set":[["canvas.path.enabled", true]]}, runTests);
 | |
| });
 | |
| 
 | |
| // Don't leak the world via the Path2D reference to its window.
 | |
| document.all;
 | |
| window.p = new Path2D();
 | |
| 
 | |
| </script>
 | 
