You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							527 lines
						
					
					
						
							18 KiB
						
					
					
				
			
		
		
	
	
							527 lines
						
					
					
						
							18 KiB
						
					
					
				<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" > | 
						|
   <head> | 
						|
   <title>Dojo Unified 2D Graphics</title> | 
						|
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | 
						|
   <script type="text/javascript"> | 
						|
   // Dojo configuration | 
						|
   djConfig = {  | 
						|
      isDebug: true | 
						|
   }; | 
						|
</script> | 
						|
<script type="text/javascript" src="../../dojo.js"></script> | 
						|
<script type="text/javascript">dojo.require("dojo.debug.console");</script> | 
						|
<!--<script type="text/javascript" src="../../src/gfx/common.js"></script>--> | 
						|
<!--<script type="text/javascript" src="../../src/gfx/path.js"></script>--> | 
						|
<!--<script type="text/javascript" src="../../src/gfx/vml.js"></script>--> | 
						|
<!--<script type="text/javascript" src="../../src/gfx/svg.js"></script>--> | 
						|
<script type="text/javascript"> | 
						|
 | 
						|
dojo.require("dojo.gfx.*"); | 
						|
dojo.require("dojo.event.*"); | 
						|
dojo.require("dojo.lang.assert"); | 
						|
 | 
						|
var gTestContainer = null; | 
						|
var gTests = {}; | 
						|
 | 
						|
function isEqual(foo, bar, prefix) | 
						|
{ | 
						|
    var flag = true; | 
						|
    if( foo != bar ) { | 
						|
        dojo.debug(prefix+":"+foo + "!=" + bar + " try dig into it" ); | 
						|
        if( foo instanceof Array ) { | 
						|
            for( var i = 0; i< foo.length; i++ ) { | 
						|
                flag = isEqual(foo[i], bar[i], prefix+"["+i+"]") && flag; | 
						|
            } | 
						|
            flag = false; | 
						|
        } else { | 
						|
            for(var x in foo) { | 
						|
                if(bar[x] != undefined ) { | 
						|
                    flag = isEqual(foo[x], bar[x], prefix+"."+x) && flag; | 
						|
                } else { | 
						|
                    dojo.debug(prefix+":"+ x + " is undefined in bar" ); | 
						|
                    flag = false; | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
    } | 
						|
    return flag; | 
						|
} | 
						|
 | 
						|
 | 
						|
function getTestSurface(testName, testDescription, width, height)  | 
						|
{ | 
						|
   width = width ? width : 300; | 
						|
   height = height ? height : 300; | 
						|
 | 
						|
   // Create a DOM node for the surface | 
						|
   var testRow = document.createElement('tr'); | 
						|
   var testCell = document.createElement('td'); | 
						|
   var testHolder = document.createElement('div'); | 
						|
   testHolder.id = testName + '_holder'; | 
						|
   var refCell = document.createElement('td'); | 
						|
   var refHolder = document.createElement('div'); | 
						|
   var refImg = document.createElement('img'); | 
						|
   refImg.src = "images/placeholder.png"; | 
						|
//   refImg.width = width; | 
						|
//   refImg.height = height; | 
						|
   refImg.id = testName + '_refimg'; | 
						|
   var imgUrl = 'images/' + testName + '.png'; | 
						|
   var errUrl = 'images/error.png'; | 
						|
   var imgToLoad = new Image(); | 
						|
   dojo.event.connect(imgToLoad, 'onload', function() { | 
						|
                         refImg.src = imgUrl; | 
						|
                      }); | 
						|
   dojo.event.connect(imgToLoad, 'onerror', function() { | 
						|
                         refImg.src = errUrl; | 
						|
                      }); | 
						|
 | 
						|
   imgToLoad.src = imgUrl; | 
						|
 | 
						|
   testCell.appendChild(testHolder); | 
						|
   testRow.appendChild(testCell); | 
						|
   refHolder.appendChild(refImg); | 
						|
   refCell.appendChild(refHolder); | 
						|
   testRow.appendChild(refCell); | 
						|
   gTestContainer.appendChild(testRow); | 
						|
 | 
						|
   var descRow = document.createElement('tr'); | 
						|
   var desc = document.createElement('td'); | 
						|
   var ref = document.createElement('td'); | 
						|
   desc.innerHTML = testDescription; | 
						|
   ref.innerHTML = testName + '.png'; | 
						|
   descRow.appendChild(desc); | 
						|
   descRow.appendChild(ref); | 
						|
   gTestContainer.appendChild(descRow); | 
						|
 | 
						|
   // see if there's a reference image available | 
						|
   // our surface is created from scratch | 
						|
   //testSurfaceHolder.width = width + "px"; | 
						|
   //testSurfaceHolder.height = height + "px"; | 
						|
   var surface = dojo.gfx.createSurface(testHolder, width, height); | 
						|
   return surface; | 
						|
} | 
						|
 | 
						|
function addTest(testName, fn) | 
						|
{ | 
						|
   gTests[testName] = fn; | 
						|
} | 
						|
 | 
						|
function runTest_nodebug(testName) | 
						|
{ | 
						|
   try { | 
						|
      var t = gTests[testName]; | 
						|
      if (!t) { | 
						|
         return 'no test named ' + t; | 
						|
      } | 
						|
      t(testName); | 
						|
      return null; // the success condition | 
						|
   } catch (e) { | 
						|
      return e.message; | 
						|
   } | 
						|
} | 
						|
 | 
						|
function runTest_debug(testName) | 
						|
{ | 
						|
      var t = gTests[testName]; | 
						|
      if (!t) { | 
						|
         return 'no test named ' + t; | 
						|
      } | 
						|
      t(testName); | 
						|
      return null; // the success condition | 
						|
} | 
						|
 | 
						|
var runTest = djConfig.isDebug ? runTest_debug : runTest_nodebug; | 
						|
 | 
						|
dojo.addOnLoad(function()  | 
						|
{ | 
						|
	gTestContainer = dojo.byId('testcontainer'); | 
						|
	var rect = { x: 0, y: 0, width: 100, height: 100 }; | 
						|
 | 
						|
	addTest('rect', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'translucent rect with rounded stroke'); | 
						|
		var red_rect = surface.createRect(rect); | 
						|
			red_rect.setFill([255, 0, 0, 0.5]); | 
						|
			red_rect.setStroke({color: "blue", width: 10, join: "round" }); | 
						|
			red_rect.setTransform({ dx: 100, dy: 100 }) | 
						|
			; | 
						|
		dojo.event.connect(red_rect.getNode(), "onclick", function(){ alert("red"); }); | 
						|
	}); | 
						|
 | 
						|
	addTest('straight_rect', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'translucent rect with no stroke'); | 
						|
		var blue_rect = surface.createRect(rect).setFill([0, 255, 0, 0.5]).setTransform({ dx: 100, dy: 100 }); | 
						|
		dojo.event.connect( blue_rect.getNode(), "onclick", function(){ blue_rect.setShape({width: blue_rect.getShape().width + 20}); }); | 
						|
	}); | 
						|
 | 
						|
	addTest('rotated_rect', function(testName){ | 
						|
		var surface = getTestSurface(testName, '30g CCW blue translucent rounded rect'); | 
						|
		dojo.debug('rotated_rect'); | 
						|
		// anonymous 30 degree CCW rotated green rectangle | 
						|
		surface.createRect({r: 20}) | 
						|
			.setFill([0, 0, 255, 0.5]) | 
						|
			// rotate it around its center and move to (100, 100) | 
						|
			.setTransform([dojo.gfx.matrix.translate(100, 100), dojo.gfx.matrix.rotategAt(30, 0, 0)]) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
	addTest('skew_rect', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'skewed rects' ); | 
						|
		// anonymous red rectangle | 
						|
		surface.createRect(rect).setFill(new dojo.gfx.color.Color([255, 0, 0, 0.5])) | 
						|
			// skew it around LB point -30d, rotate it around LB point 30d, and move it to (100, 100) | 
						|
			.setTransform([dojo.gfx.matrix.translate(100, 100), dojo.gfx.matrix.rotategAt(30, 0, 100), dojo.gfx.matrix.skewXgAt(-30, 0, 100)]); | 
						|
		// anonymous blue rectangle | 
						|
		surface.createRect(rect).setFill(new dojo.gfx.color.Color([0, 0, 255, 0.5])) | 
						|
			// skew it around LB point -30d, and move it to (100, 100) | 
						|
			.setTransform([dojo.gfx.matrix.translate(100, 100), dojo.gfx.matrix.skewXgAt(-30, 0, 100)]); | 
						|
		// anonymous yellow rectangle | 
						|
		surface.createRect(rect).setFill(new dojo.gfx.color.Color([255, 255, 0, 0.25])) | 
						|
			// move it to (100, 100) | 
						|
			.setTransform(dojo.gfx.matrix.translate(100, 100)); | 
						|
	}); | 
						|
 | 
						|
	addTest('matrix_rect', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'all matrix operations, check debug output for more details'); | 
						|
 | 
						|
		var group = surface.createGroup(); | 
						|
		 | 
						|
		var blue_rect = group.createRect(rect).setFill([0, 0, 255, 0.5]).applyTransform(dojo.gfx.matrix.identity); | 
						|
		dojo.debug( "blue_rect: rect with identity" ); | 
						|
 | 
						|
		group.createRect(rect).setFill([0, 255, 0, 0.5]).applyTransform(dojo.gfx.matrix.translate(30, 40)); | 
						|
		dojo.debug( "lime_rect: translate(30,40) " ); | 
						|
		 | 
						|
		group.createRect(rect).setFill([255, 0, 0, 0.5]).applyTransform(dojo.gfx.matrix.rotateg(30)); | 
						|
		dojo.debug( "red_rect: rotate 30 degree counterclockwise " ); | 
						|
 | 
						|
		group.createRect(rect).setFill([0, 255, 255, 0.5]) | 
						|
			.applyTransform(dojo.gfx.matrix.scale({x:1.5, y:0.5})) | 
						|
			.applyTransform(dojo.gfx.matrix.translate(-40, 220)) | 
						|
			; | 
						|
		dojo.debug( "lightblue_rect: scale(1.5, 0.5)" ); | 
						|
 | 
						|
		group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 0, 255, 0.5]).applyTransform(dojo.gfx.matrix.flipX); | 
						|
		dojo.debug( "pink_rect: flipX" ); | 
						|
 | 
						|
		group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 255, 0, 0.5]).applyTransform(dojo.gfx.matrix.flipY); | 
						|
		dojo.debug( "yellow_rect: flipY" ); | 
						|
 | 
						|
		group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([128, 0, 128, 0.5]).applyTransform(dojo.gfx.matrix.flipXY); | 
						|
		dojo.debug( "purple_rect: flipXY" ); | 
						|
 | 
						|
		group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 128, 0, 0.5]).applyTransform(dojo.gfx.matrix.skewXg(15)); | 
						|
		dojo.debug( "purple_rect: skewXg 15 degree" ); | 
						|
 | 
						|
		group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([0, 0, 0, 0.5]).applyTransform(dojo.gfx.matrix.skewYg(50)); | 
						|
		dojo.debug( "black_rect: skewXg 50 degree" ); | 
						|
 | 
						|
		// move | 
						|
		group | 
						|
			.setTransform({ xx: 1.5, yy: 0.5, dx: 100, dy: 100 }) | 
						|
			.applyTransform(dojo.gfx.matrix.rotateg(30)) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
    | 
						|
	addTest('attach', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'Attach to existed shape'); | 
						|
		var red_rect = surface.createRect(rect) | 
						|
			.setShape({ width: 75 }) | 
						|
			.setFill([255, 0, 0, 0.5]) | 
						|
			.setStroke({ color: "blue", width: 1 }) | 
						|
			.setTransform({ dx: 50, dy: 50, xx: 1, xy: 0.5, yx: 0.7, yy: 1.1 }) | 
						|
			; | 
						|
 | 
						|
		dojo.debug("attaching !"); | 
						|
		// now attach it! | 
						|
		var ar = dojo.gfx.attachNode(red_rect.rawNode); | 
						|
		dojo.lang.assert( ar.rawNode == red_rect.rawNode ); | 
						|
 | 
						|
		// FIXME: more generic method to compare two dictionary? | 
						|
		dojo.debug("attach shape: "); | 
						|
		isEqual(ar.shape, red_rect.shape, "rect.shape"); | 
						|
		dojo.debug("attach matrix: "); | 
						|
		isEqual(ar.matrix, red_rect.matrix, "rect.matrix"); | 
						|
		dojo.debug("attach strokeStyle: "); | 
						|
		isEqual(ar.strokeStyle, red_rect.strokeStyle, "rect.strokeStyle"); | 
						|
		dojo.debug("attach fillStyle: "); | 
						|
		isEqual(ar.fillStyle, red_rect.fillStyle, "rect.fillStyle"); | 
						|
	}); | 
						|
 | 
						|
	// test circle | 
						|
	addTest('circle', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'translucent green circle'); | 
						|
		var circle = { cx: 130, cy: 130, r: 50 }; | 
						|
		surface.createCircle(circle).setFill([0, 255, 0, 0.5]).setTransform({ dx: 20, dy: 20 }); | 
						|
	}); | 
						|
 | 
						|
	// test line | 
						|
	addTest('line', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'straight red line'); | 
						|
		var line = { x1: 20, y1: 20, x2: 100, y2: 120 }; | 
						|
		surface.createLine(line).setFill([255, 0, 0, 0.5]).setStroke({color: "red", width: 1}).setTransform({ dx:70, dy: 100 }); | 
						|
	}); | 
						|
 | 
						|
	// test ellipse  | 
						|
	addTest('ellipse', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'translucent cyan ellipse'); | 
						|
		var ellipse = { cx: 50, cy: 80, rx: 50, ry: 80 }; | 
						|
		surface.createEllipse(ellipse).setFill([0, 255, 255, 0.5]).setTransform({ dx: 30, dy: 70 }); | 
						|
	}); | 
						|
 | 
						|
	// test polyline | 
						|
	addTest('polyline', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'unfilled open polyline'); | 
						|
		var points = [ {x: 10, y: 20}, {x: 40, y: 70}, {x: 120, y: 50}, {x: 90, y: 90} ]; | 
						|
		surface.createPolyline(points).setFill(null).setStroke({ color: "blue", width: 1 }).setTransform({ dx: 15, dy: 0 }); | 
						|
	}); | 
						|
 | 
						|
	// test polygon | 
						|
	addTest('polygon', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'filled polygon'); | 
						|
		var points2 = [{x: 100, y: 0}, {x: 200, y: 40}, {x: 180, y: 150}, {x: 60, y: 170}, {x: 20, y: 100}]; | 
						|
		surface.createPolyline(points2).setFill([0, 128, 255, 0.6]).setTransform({dx:30, dy: 20}); | 
						|
	}); | 
						|
 | 
						|
	// test path: lineTo, moveTo, closePath | 
						|
	addTest('lineTo', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'lineTo, moveTo, closePath'); | 
						|
		surface.createPath() | 
						|
			.moveTo(10, 20).lineTo(80, 150) | 
						|
			.setAbsoluteMode(false).lineTo(40, 0) | 
						|
			.setAbsoluteMode(true).lineTo(180, 100) | 
						|
			.setAbsoluteMode(false).lineTo(0, -30).lineTo(-30, -50) | 
						|
			.closePath() | 
						|
			.setStroke({ color: "red", width: 1 }) | 
						|
			.setFill(null) | 
						|
			.setTransform({ dx: 10, dy: 18 }) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
	addTest('setPath', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'setPath example with lineTo moveTo'); | 
						|
		surface.createPath() | 
						|
			.moveTo(10, 20).lineTo(80, 150) | 
						|
			.setAbsoluteMode(false).lineTo(40,0) | 
						|
			.setAbsoluteMode(true).lineTo(180, 100) | 
						|
			.setAbsoluteMode(false).lineTo(0, -30).lineTo(-30, -50) | 
						|
			.curveTo(10, -80, -150, -10, -90, -10) | 
						|
			.closePath() | 
						|
			.setStroke({ color: "red", width: 1 }) | 
						|
			.setFill(null) | 
						|
			.setTransform({ dx: 10, dy: 58 }) | 
						|
			; | 
						|
 | 
						|
		surface.createPath({ path: "M10,20 L80,150 l40,0 L180,100 l0,-30 l-30,-50 c10,-80 -150,-10 -90,-10 z" }) | 
						|
			.setFill(null) | 
						|
			.setStroke({ color: "blue", width: 1 }) | 
						|
			.setTransform({ dx: 50, dy: 78 }) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
	// test arcTo  | 
						|
	addTest('arcTo', function(testName){ | 
						|
		var surface = getTestSurface(testName, 'arcTo: from 0 to 360 degree, w/ 30 degree of x axis rotation, rendered with different color'); | 
						|
 | 
						|
		var m = dojo.gfx.matrix; | 
						|
		var g1 = surface.createGroup(); | 
						|
		var g2 = g1.createGroup(); | 
						|
 | 
						|
		var rx = 100, ry = 60, xRotg = 30; | 
						|
		var startPoint = m.multiplyPoint(m.rotateg(xRotg), {x: -rx, y: 0  }); | 
						|
		var endPoint   = m.multiplyPoint(m.rotateg(xRotg), {x: 0,   y: -ry}); | 
						|
	     | 
						|
		var re1 = g1.createPath() | 
						|
			.moveTo(startPoint) | 
						|
			.arcTo(rx, ry, xRotg, true, false, endPoint) | 
						|
			.setStroke({color: "red"}) | 
						|
			; | 
						|
		var ge1 = g1.createPath() | 
						|
			.moveTo(re1.getLastPosition()) | 
						|
			.arcTo(rx, ry, xRotg, false, false, startPoint) | 
						|
			.setStroke({color: "blue"}) | 
						|
			; | 
						|
		var re2 = g2.createPath() | 
						|
			.moveTo(startPoint) | 
						|
			.arcTo(rx, ry, xRotg, false, true, endPoint) | 
						|
			.setStroke({color: "red"}) | 
						|
			; | 
						|
		var ge2 = g2.createPath() | 
						|
			.moveTo(re2.getLastPosition()) | 
						|
			.arcTo(rx, ry, xRotg, true, true, startPoint) | 
						|
			.setStroke({color: "blue"}) | 
						|
			; | 
						|
			 | 
						|
		g1.setTransform({dx: 150, dy: 150}); | 
						|
		g2.setTransform({dx: 10,  dy: 10}); | 
						|
	}); | 
						|
 | 
						|
	// test path: curveTo, smoothCurveTo | 
						|
	addTest('curveTo', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'curveTo, smoothCurveTo'); | 
						|
		surface.createPath() | 
						|
			.moveTo(10, 20).curveTo(50, 50, 50, 100, 150, 100).smoothCurveTo(300, 300, 200, 200) | 
						|
			.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 }) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
	// test path: curveTo, smoothCurveTo with relative. | 
						|
	addTest('curveTo2', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'curveTo, smoothCurveTo with relative coordination'); | 
						|
		surface.createPath() | 
						|
			.moveTo(10, 20).curveTo(50, 50, 50, 100, 150, 100) | 
						|
			.setAbsoluteMode(false).smoothCurveTo(150, 200, 50, 100) | 
						|
			.setAbsoluteMode(true).smoothCurveTo(50, 100, 10, 230) | 
						|
			.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 }) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
	// test path: curveTo, smoothCurveTo with relative. | 
						|
	addTest('qbCurveTo', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'qbcurveTo, smoothQBCurveTo' ); | 
						|
		surface.createPath() | 
						|
			.moveTo(10, 15).qbCurveTo(50, 50, 100, 100).smoothQBCurveTo(150, 20) | 
						|
			.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 }) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
	addTest('qbCurveTo2', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'qbcurveTo, smoothQBCurveTo with relative' ); | 
						|
		surface.createPath() | 
						|
			.moveTo(10, 20).qbCurveTo(50, 50, 100, 100) | 
						|
			.setAbsoluteMode(false).smoothQBCurveTo(50, -80) | 
						|
			.setAbsoluteMode(true).smoothQBCurveTo(200, 80) | 
						|
			.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 }) | 
						|
			; | 
						|
	}); | 
						|
 | 
						|
	// test defines, linearGradient | 
						|
	addTest('linearGradient', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'linear gradient fill'); | 
						|
		// this is an example to split the linearGradient from setFill: | 
						|
		var lg = { | 
						|
			type: "linear", | 
						|
			x1: 0, y1: 0, x2: 75, y2: 50, | 
						|
			colors: [ | 
						|
				{ offset: 0, color: "#F60" }, | 
						|
				{ offset: 1, color: "#FF6" } | 
						|
			] | 
						|
		}; | 
						|
		surface.createRect(rect).setFill(lg).setTransform({ dx: 40, dy: 100 }); | 
						|
	}); | 
						|
 | 
						|
	// TODO: test radialGradient | 
						|
	addTest('radialGradient', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'radial gradient fill'); | 
						|
		// this is a total inline implementation compared with previous one. | 
						|
		var rg = { | 
						|
			type: "radial", | 
						|
			cx: 100, cy: 100, r: 100, | 
						|
			colors: [ | 
						|
				{ offset:   0, color: "red" }, | 
						|
				{ offset: 0.5, color: "green" }, | 
						|
				{ offset:   1, color: "blue" } | 
						|
			] | 
						|
		}; | 
						|
		 | 
						|
		surface.createCircle({cx: 100, cy: 100, r: 100}) | 
						|
			.setStroke({}) | 
						|
			.setFill(rg) | 
						|
			.setTransform({dx: 40, dy: 30}) | 
						|
			; | 
						|
//		surface.createRect(rect) | 
						|
//			.setShape({width: 200}) | 
						|
//			.setStroke({}) | 
						|
//			.setFill(rg) | 
						|
//			.setTransform({dx: 40, dy: 30}) | 
						|
//			; | 
						|
	}); | 
						|
 | 
						|
	// TODO: test defines,pattern, path | 
						|
	addTest('pattern', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'pattern fill'); | 
						|
		var pat = new dojo.gfx.Pattern( {x:0, y:0, width:40, height:40, patternUnits:"userSpaceOnUse", viewBox:[0, 0, 10, 10] }); | 
						|
		pat.createRect().setRect({width:25, height:20}). | 
						|
		setFill(new dojo.gfx.color.Color("red")); | 
						|
		surface.createRect(rect).setFill(pat). | 
						|
		setStroke({ color: new dojo.gfx.color.Color("blue"), width: 2}). | 
						|
		setTransform({dx: 40, dy: 30}); | 
						|
	}); | 
						|
 | 
						|
	addTest('attach_gradient', function(testName) { | 
						|
		var surface = getTestSurface(testName, 'attach gradient fill'); | 
						|
		// this is an example to split the linearGradient from setFill: | 
						|
		var lg = { | 
						|
			type: "linear", | 
						|
			x1: 0, y1: 0, x2: 75, y2: 50, | 
						|
			colors: [ | 
						|
				{ offset:   0, color: "#F60" }, | 
						|
				{ offset: 0.5, color: "#FAF" }, | 
						|
				{ offset:   1, color: "#FF6" } | 
						|
			] | 
						|
		}; | 
						|
 | 
						|
		var lgr = surface.createRect(rect).setFill(lg).setTransform({ dx: 40, dy: 100 }); | 
						|
 | 
						|
		var ar = dojo.gfx.attachNode(lgr.rawNode); | 
						|
		// FIXME: more generic method to compare two dictionary? | 
						|
		dojo.debug("attach_gradient!"); | 
						|
 | 
						|
		dojo.debug("attach shape: "); | 
						|
		isEqual(lgr.shape, ar.shape, "rect.shape"); | 
						|
		dojo.debug("attach matrix: "); | 
						|
		isEqual(lgr.matrix, ar.matrix, "rect.matrix"); | 
						|
		dojo.debug("attach strokeStyle: "); | 
						|
		isEqual(lgr.strokeStyle, ar.strokeStyle, "rect.strokeStyle"); | 
						|
		dojo.debug("attach fillStyle: "); | 
						|
		isEqual(lgr.fillStyle.gradient, ar.fillStyle.gradient, "rect.fillStyle.gradient"); | 
						|
		//isEqual(lgr.fillStyle.id, ar.fillStyle.id, "rect.fillStyle.id"); | 
						|
	}); | 
						|
 | 
						|
	var gTestsToRun = [ | 
						|
		'rect', | 
						|
		'straight_rect', | 
						|
		'rotated_rect', | 
						|
		'skew_rect', | 
						|
		'matrix_rect',  | 
						|
		'attach', | 
						|
		'attach_gradient', | 
						|
		'circle', | 
						|
		'arcTo', | 
						|
		'line', | 
						|
		'ellipse', | 
						|
		'polyline', | 
						|
		'polygon', | 
						|
		'lineTo', | 
						|
		'setPath', | 
						|
		'curveTo', | 
						|
		'curveTo2', | 
						|
		//'qbCurveTo', | 
						|
		//'qbCurveTo2', | 
						|
		'linearGradient', | 
						|
		'radialGradient' | 
						|
		//'pattern' | 
						|
	]; | 
						|
 | 
						|
	for (var i = 0; i < gTestsToRun.length; ++i) { | 
						|
		var testName = gTestsToRun[i]; | 
						|
		var err = runTest(testName); | 
						|
		if (err) { | 
						|
			getTestSurface(testName, testName + ' FAILED (' + err + ')'); | 
						|
		} | 
						|
	} | 
						|
 | 
						|
}); // end onload | 
						|
</script> | 
						|
<style> | 
						|
   td { border: 1px solid black; text-align: left; vertical-align: top; } | 
						|
   v:group { text-align: left; } | 
						|
</style> | 
						|
   </head> | 
						|
   <body> | 
						|
   <table> | 
						|
   <tbody id="testcontainer"> | 
						|
   </tbody> | 
						|
   </table> | 
						|
   </body> | 
						|
   </html>
 | 
						|
 |