root / trunk / web / dojo / dojox / gfx.js.uncompressed.js @ 10
History | View | Annotate | Download (30.8 KB)
| 1 | 9 | andrej.cim | /*
|
|---|---|---|---|
| 2 | Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
|
||
| 3 | Available via Academic Free License >= 2.1 OR the modified BSD license.
|
||
| 4 | see: http://dojotoolkit.org/license for details
|
||
| 5 | */
|
||
| 6 | |||
| 7 | /*
|
||
| 8 | This is an optimized version of Dojo, built for deployment and not for
|
||
| 9 | development. To get sources and documentation, please visit:
|
||
| 10 | |||
| 11 | http://dojotoolkit.org
|
||
| 12 | */
|
||
| 13 | |||
| 14 | if(!dojo._hasResource["dojox.gfx.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
||
| 15 | dojo._hasResource["dojox.gfx.matrix"] = true; |
||
| 16 | dojo.provide("dojox.gfx.matrix");
|
||
| 17 | |||
| 18 | (function(){
|
||
| 19 | var m = dojox.gfx.matrix;
|
||
| 20 | |||
| 21 | // candidates for dojox.math:
|
||
| 22 | var _degToRadCache = {};
|
||
| 23 | m._degToRad = function(degree){ |
||
| 24 | return _degToRadCache[degree] || (_degToRadCache[degree] = (Math.PI * degree / 180)); |
||
| 25 | }; |
||
| 26 | m._radToDeg = function(radian){ return radian / Math.PI * 180; }; |
||
| 27 | |||
| 28 | m.Matrix2D = function(arg){ |
||
| 29 | // summary: a 2D matrix object
|
||
| 30 | // description: Normalizes a 2D matrix-like object. If arrays is passed,
|
||
| 31 | // all objects of the array are normalized and multiplied sequentially.
|
||
| 32 | // arg: Object
|
||
| 33 | // a 2D matrix-like object, a number, or an array of such objects
|
||
| 34 | if(arg){
|
||
| 35 | if(typeof arg == "number"){ |
||
| 36 | this.xx = this.yy = arg; |
||
| 37 | }else if(arg instanceof Array){ |
||
| 38 | if(arg.length > 0){ |
||
| 39 | var matrix = m.normalize(arg[0]); |
||
| 40 | // combine matrices
|
||
| 41 | for(var i = 1; i < arg.length; ++i){ |
||
| 42 | var l = matrix, r = dojox.gfx.matrix.normalize(arg[i]);
|
||
| 43 | matrix = new m.Matrix2D();
|
||
| 44 | matrix.xx = l.xx * r.xx + l.xy * r.yx; |
||
| 45 | matrix.xy = l.xx * r.xy + l.xy * r.yy; |
||
| 46 | matrix.yx = l.yx * r.xx + l.yy * r.yx; |
||
| 47 | matrix.yy = l.yx * r.xy + l.yy * r.yy; |
||
| 48 | matrix.dx = l.xx * r.dx + l.xy * r.dy + l.dx; |
||
| 49 | matrix.dy = l.yx * r.dx + l.yy * r.dy + l.dy; |
||
| 50 | } |
||
| 51 | dojo.mixin(this, matrix);
|
||
| 52 | } |
||
| 53 | }else{
|
||
| 54 | dojo.mixin(this, arg);
|
||
| 55 | } |
||
| 56 | } |
||
| 57 | }; |
||
| 58 | |||
| 59 | // the default (identity) matrix, which is used to fill in missing values
|
||
| 60 | dojo.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0});
|
||
| 61 | |||
| 62 | dojo.mixin(m, {
|
||
| 63 | // summary: class constants, and methods of dojox.gfx.matrix
|
||
| 64 | |||
| 65 | // matrix constants
|
||
| 66 | |||
| 67 | // identity: dojox.gfx.matrix.Matrix2D
|
||
| 68 | // an identity matrix constant: identity * (x, y) == (x, y)
|
||
| 69 | identity: new m.Matrix2D(), |
||
| 70 | |||
| 71 | // flipX: dojox.gfx.matrix.Matrix2D
|
||
| 72 | // a matrix, which reflects points at x = 0 line: flipX * (x, y) == (-x, y)
|
||
| 73 | flipX: new m.Matrix2D({xx: -1}), |
||
| 74 | |||
| 75 | // flipY: dojox.gfx.matrix.Matrix2D
|
||
| 76 | // a matrix, which reflects points at y = 0 line: flipY * (x, y) == (x, -y)
|
||
| 77 | flipY: new m.Matrix2D({yy: -1}), |
||
| 78 | |||
| 79 | // flipXY: dojox.gfx.matrix.Matrix2D
|
||
| 80 | // a matrix, which reflects points at the origin of coordinates: flipXY * (x, y) == (-x, -y)
|
||
| 81 | flipXY: new m.Matrix2D({xx: -1, yy: -1}), |
||
| 82 | |||
| 83 | // matrix creators
|
||
| 84 | |||
| 85 | translate: function(a, b){ |
||
| 86 | // summary: forms a translation matrix
|
||
| 87 | // description: The resulting matrix is used to translate (move) points by specified offsets.
|
||
| 88 | // a: Number: an x coordinate value
|
||
| 89 | // b: Number: a y coordinate value
|
||
| 90 | if(arguments.length > 1){ |
||
| 91 | return new m.Matrix2D({dx: a, dy: b}); // dojox.gfx.matrix.Matrix2D |
||
| 92 | } |
||
| 93 | // branch
|
||
| 94 | // a: dojox.gfx.Point: a point-like object, which specifies offsets for both dimensions
|
||
| 95 | // b: null
|
||
| 96 | return new m.Matrix2D({dx: a.x, dy: a.y}); // dojox.gfx.matrix.Matrix2D |
||
| 97 | }, |
||
| 98 | scale: function(a, b){ |
||
| 99 | // summary: forms a scaling matrix
|
||
| 100 | // description: The resulting matrix is used to scale (magnify) points by specified offsets.
|
||
| 101 | // a: Number: a scaling factor used for the x coordinate
|
||
| 102 | // b: Number: a scaling factor used for the y coordinate
|
||
| 103 | if(arguments.length > 1){ |
||
| 104 | return new m.Matrix2D({xx: a, yy: b}); // dojox.gfx.matrix.Matrix2D |
||
| 105 | } |
||
| 106 | if(typeof a == "number"){ |
||
| 107 | // branch
|
||
| 108 | // a: Number: a uniform scaling factor used for the both coordinates
|
||
| 109 | // b: null
|
||
| 110 | return new m.Matrix2D({xx: a, yy: a}); // dojox.gfx.matrix.Matrix2D |
||
| 111 | } |
||
| 112 | // branch
|
||
| 113 | // a: dojox.gfx.Point: a point-like object, which specifies scale factors for both dimensions
|
||
| 114 | // b: null
|
||
| 115 | return new m.Matrix2D({xx: a.x, yy: a.y}); // dojox.gfx.matrix.Matrix2D |
||
| 116 | }, |
||
| 117 | rotate: function(angle){ |
||
| 118 | // summary: forms a rotating matrix
|
||
| 119 | // description: The resulting matrix is used to rotate points
|
||
| 120 | // around the origin of coordinates (0, 0) by specified angle.
|
||
| 121 | // angle: Number: an angle of rotation in radians (>0 for CW)
|
||
| 122 | var c = Math.cos(angle);
|
||
| 123 | var s = Math.sin(angle);
|
||
| 124 | return new m.Matrix2D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx.matrix.Matrix2D |
||
| 125 | }, |
||
| 126 | rotateg: function(degree){ |
||
| 127 | // summary: forms a rotating matrix
|
||
| 128 | // description: The resulting matrix is used to rotate points
|
||
| 129 | // around the origin of coordinates (0, 0) by specified degree.
|
||
| 130 | // See dojox.gfx.matrix.rotate() for comparison.
|
||
| 131 | // degree: Number: an angle of rotation in degrees (>0 for CW)
|
||
| 132 | return m.rotate(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D |
||
| 133 | }, |
||
| 134 | skewX: function(angle) { |
||
| 135 | // summary: forms an x skewing matrix
|
||
| 136 | // description: The resulting matrix is used to skew points in the x dimension
|
||
| 137 | // around the origin of coordinates (0, 0) by specified angle.
|
||
| 138 | // angle: Number: an skewing angle in radians
|
||
| 139 | return new m.Matrix2D({xy: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D |
||
| 140 | }, |
||
| 141 | skewXg: function(degree){ |
||
| 142 | // summary: forms an x skewing matrix
|
||
| 143 | // description: The resulting matrix is used to skew points in the x dimension
|
||
| 144 | // around the origin of coordinates (0, 0) by specified degree.
|
||
| 145 | // See dojox.gfx.matrix.skewX() for comparison.
|
||
| 146 | // degree: Number: an skewing angle in degrees
|
||
| 147 | return m.skewX(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D |
||
| 148 | }, |
||
| 149 | skewY: function(angle){ |
||
| 150 | // summary: forms a y skewing matrix
|
||
| 151 | // description: The resulting matrix is used to skew points in the y dimension
|
||
| 152 | // around the origin of coordinates (0, 0) by specified angle.
|
||
| 153 | // angle: Number: an skewing angle in radians
|
||
| 154 | return new m.Matrix2D({yx: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D |
||
| 155 | }, |
||
| 156 | skewYg: function(degree){ |
||
| 157 | // summary: forms a y skewing matrix
|
||
| 158 | // description: The resulting matrix is used to skew points in the y dimension
|
||
| 159 | // around the origin of coordinates (0, 0) by specified degree.
|
||
| 160 | // See dojox.gfx.matrix.skewY() for comparison.
|
||
| 161 | // degree: Number: an skewing angle in degrees
|
||
| 162 | return m.skewY(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D |
||
| 163 | }, |
||
| 164 | reflect: function(a, b){ |
||
| 165 | // summary: forms a reflection matrix
|
||
| 166 | // description: The resulting matrix is used to reflect points around a vector,
|
||
| 167 | // which goes through the origin.
|
||
| 168 | // a: dojox.gfx.Point: a point-like object, which specifies a vector of reflection
|
||
| 169 | // b: null
|
||
| 170 | if(arguments.length == 1){ |
||
| 171 | b = a.y; |
||
| 172 | a = a.x; |
||
| 173 | } |
||
| 174 | // branch
|
||
| 175 | // a: Number: an x coordinate value
|
||
| 176 | // b: Number: a y coordinate value
|
||
| 177 | |||
| 178 | // make a unit vector
|
||
| 179 | var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = 2 * a * b / n2; |
||
| 180 | return new m.Matrix2D({xx: 2 * a2 / n2 - 1, xy: xy, yx: xy, yy: 2 * b2 / n2 - 1}); // dojox.gfx.matrix.Matrix2D |
||
| 181 | }, |
||
| 182 | project: function(a, b){ |
||
| 183 | // summary: forms an orthogonal projection matrix
|
||
| 184 | // description: The resulting matrix is used to project points orthogonally on a vector,
|
||
| 185 | // which goes through the origin.
|
||
| 186 | // a: dojox.gfx.Point: a point-like object, which specifies a vector of projection
|
||
| 187 | // b: null
|
||
| 188 | if(arguments.length == 1){ |
||
| 189 | b = a.y; |
||
| 190 | a = a.x; |
||
| 191 | } |
||
| 192 | // branch
|
||
| 193 | // a: Number: an x coordinate value
|
||
| 194 | // b: Number: a y coordinate value
|
||
| 195 | |||
| 196 | // make a unit vector
|
||
| 197 | var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = a * b / n2;
|
||
| 198 | return new m.Matrix2D({xx: a2 / n2, xy: xy, yx: xy, yy: b2 / n2}); // dojox.gfx.matrix.Matrix2D |
||
| 199 | }, |
||
| 200 | |||
| 201 | // ensure matrix 2D conformance
|
||
| 202 | normalize: function(matrix){ |
||
| 203 | // summary: converts an object to a matrix, if necessary
|
||
| 204 | // description: Converts any 2D matrix-like object or an array of
|
||
| 205 | // such objects to a valid dojox.gfx.matrix.Matrix2D object.
|
||
| 206 | // matrix: Object: an object, which is converted to a matrix, if necessary
|
||
| 207 | return (matrix instanceof m.Matrix2D) ? matrix : new m.Matrix2D(matrix); // dojox.gfx.matrix.Matrix2D |
||
| 208 | }, |
||
| 209 | |||
| 210 | // common operations
|
||
| 211 | |||
| 212 | clone: function(matrix){ |
||
| 213 | // summary: creates a copy of a 2D matrix
|
||
| 214 | // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be cloned
|
||
| 215 | var obj = new m.Matrix2D(); |
||
| 216 | for(var i in matrix){ |
||
| 217 | if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i]; |
||
| 218 | } |
||
| 219 | return obj; // dojox.gfx.matrix.Matrix2D |
||
| 220 | }, |
||
| 221 | invert: function(matrix){ |
||
| 222 | // summary: inverts a 2D matrix
|
||
| 223 | // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be inverted
|
||
| 224 | var M = m.normalize(matrix),
|
||
| 225 | D = M.xx * M.yy - M.xy * M.yx, |
||
| 226 | M = new m.Matrix2D({
|
||
| 227 | xx: M.yy/D, xy: -M.xy/D, |
||
| 228 | yx: -M.yx/D, yy: M.xx/D, |
||
| 229 | dx: (M.xy * M.dy - M.yy * M.dx) / D,
|
||
| 230 | dy: (M.yx * M.dx - M.xx * M.dy) / D
|
||
| 231 | }); |
||
| 232 | return M; // dojox.gfx.matrix.Matrix2D |
||
| 233 | }, |
||
| 234 | _multiplyPoint: function(matrix, x, y){ |
||
| 235 | // summary: applies a matrix to a point
|
||
| 236 | // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
|
||
| 237 | // x: Number: an x coordinate of a point
|
||
| 238 | // y: Number: a y coordinate of a point
|
||
| 239 | return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y: matrix.yx * x + matrix.yy * y + matrix.dy}; // dojox.gfx.Point |
||
| 240 | }, |
||
| 241 | multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b){ |
||
| 242 | // summary: applies a matrix to a point
|
||
| 243 | // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
|
||
| 244 | // a: Number: an x coordinate of a point
|
||
| 245 | // b: Number: a y coordinate of a point
|
||
| 246 | var M = m.normalize(matrix);
|
||
| 247 | if(typeof a == "number" && typeof b == "number"){ |
||
| 248 | return m._multiplyPoint(M, a, b); // dojox.gfx.Point |
||
| 249 | } |
||
| 250 | // branch
|
||
| 251 | // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
|
||
| 252 | // a: dojox.gfx.Point: a point
|
||
| 253 | // b: null
|
||
| 254 | return m._multiplyPoint(M, a.x, a.y); // dojox.gfx.Point |
||
| 255 | }, |
||
| 256 | multiply: function(matrix){ |
||
| 257 | // summary: combines matrices by multiplying them sequentially in the given order
|
||
| 258 | // matrix: dojox.gfx.matrix.Matrix2D...: a 2D matrix-like object,
|
||
| 259 | // all subsequent arguments are matrix-like objects too
|
||
| 260 | var M = m.normalize(matrix);
|
||
| 261 | // combine matrices
|
||
| 262 | for(var i = 1; i < arguments.length; ++i){ |
||
| 263 | var l = M, r = m.normalize(arguments[i]); |
||
| 264 | M = new m.Matrix2D();
|
||
| 265 | M.xx = l.xx * r.xx + l.xy * r.yx; |
||
| 266 | M.xy = l.xx * r.xy + l.xy * r.yy; |
||
| 267 | M.yx = l.yx * r.xx + l.yy * r.yx; |
||
| 268 | M.yy = l.yx * r.xy + l.yy * r.yy; |
||
| 269 | M.dx = l.xx * r.dx + l.xy * r.dy + l.dx; |
||
| 270 | M.dy = l.yx * r.dx + l.yy * r.dy + l.dy; |
||
| 271 | } |
||
| 272 | return M; // dojox.gfx.matrix.Matrix2D |
||
| 273 | }, |
||
| 274 | |||
| 275 | // high level operations
|
||
| 276 | |||
| 277 | _sandwich: function(matrix, x, y){ |
||
| 278 | // summary: applies a matrix at a centrtal point
|
||
| 279 | // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object, which is applied at a central point
|
||
| 280 | // x: Number: an x component of the central point
|
||
| 281 | // y: Number: a y component of the central point
|
||
| 282 | return m.multiply(m.translate(x, y), matrix, m.translate(-x, -y)); // dojox.gfx.matrix.Matrix2D |
||
| 283 | }, |
||
| 284 | scaleAt: function(a, b, c, d){ |
||
| 285 | // summary: scales a picture using a specified point as a center of scaling
|
||
| 286 | // description: Compare with dojox.gfx.matrix.scale().
|
||
| 287 | // a: Number: a scaling factor used for the x coordinate
|
||
| 288 | // b: Number: a scaling factor used for the y coordinate
|
||
| 289 | // c: Number: an x component of a central point
|
||
| 290 | // d: Number: a y component of a central point
|
||
| 291 | |||
| 292 | // accepts several signatures:
|
||
| 293 | // 1) uniform scale factor, Point
|
||
| 294 | // 2) uniform scale factor, x, y
|
||
| 295 | // 3) x scale, y scale, Point
|
||
| 296 | // 4) x scale, y scale, x, y
|
||
| 297 | |||
| 298 | switch(arguments.length){ |
||
| 299 | case 4: |
||
| 300 | // a and b are scale factor components, c and d are components of a point
|
||
| 301 | return m._sandwich(m.scale(a, b), c, d); // dojox.gfx.matrix.Matrix2D |
||
| 302 | case 3: |
||
| 303 | if(typeof c == "number"){ |
||
| 304 | // branch
|
||
| 305 | // a: Number: a uniform scaling factor used for both coordinates
|
||
| 306 | // b: Number: an x component of a central point
|
||
| 307 | // c: Number: a y component of a central point
|
||
| 308 | // d: null
|
||
| 309 | return m._sandwich(m.scale(a), b, c); // dojox.gfx.matrix.Matrix2D |
||
| 310 | } |
||
| 311 | // branch
|
||
| 312 | // a: Number: a scaling factor used for the x coordinate
|
||
| 313 | // b: Number: a scaling factor used for the y coordinate
|
||
| 314 | // c: dojox.gfx.Point: a central point
|
||
| 315 | // d: null
|
||
| 316 | return m._sandwich(m.scale(a, b), c.x, c.y); // dojox.gfx.matrix.Matrix2D |
||
| 317 | } |
||
| 318 | // branch
|
||
| 319 | // a: Number: a uniform scaling factor used for both coordinates
|
||
| 320 | // b: dojox.gfx.Point: a central point
|
||
| 321 | // c: null
|
||
| 322 | // d: null
|
||
| 323 | return m._sandwich(m.scale(a), b.x, b.y); // dojox.gfx.matrix.Matrix2D |
||
| 324 | }, |
||
| 325 | rotateAt: function(angle, a, b){ |
||
| 326 | // summary: rotates a picture using a specified point as a center of rotation
|
||
| 327 | // description: Compare with dojox.gfx.matrix.rotate().
|
||
| 328 | // angle: Number: an angle of rotation in radians (>0 for CW)
|
||
| 329 | // a: Number: an x component of a central point
|
||
| 330 | // b: Number: a y component of a central point
|
||
| 331 | |||
| 332 | // accepts several signatures:
|
||
| 333 | // 1) rotation angle in radians, Point
|
||
| 334 | // 2) rotation angle in radians, x, y
|
||
| 335 | |||
| 336 | if(arguments.length > 2){ |
||
| 337 | return m._sandwich(m.rotate(angle), a, b); // dojox.gfx.matrix.Matrix2D |
||
| 338 | } |
||
| 339 | |||
| 340 | // branch
|
||
| 341 | // angle: Number: an angle of rotation in radians (>0 for CCW)
|
||
| 342 | // a: dojox.gfx.Point: a central point
|
||
| 343 | // b: null
|
||
| 344 | return m._sandwich(m.rotate(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D |
||
| 345 | }, |
||
| 346 | rotategAt: function(degree, a, b){ |
||
| 347 | // summary: rotates a picture using a specified point as a center of rotation
|
||
| 348 | // description: Compare with dojox.gfx.matrix.rotateg().
|
||
| 349 | // degree: Number: an angle of rotation in degrees (>0 for CW)
|
||
| 350 | // a: Number: an x component of a central point
|
||
| 351 | // b: Number: a y component of a central point
|
||
| 352 | |||
| 353 | // accepts several signatures:
|
||
| 354 | // 1) rotation angle in degrees, Point
|
||
| 355 | // 2) rotation angle in degrees, x, y
|
||
| 356 | |||
| 357 | if(arguments.length > 2){ |
||
| 358 | return m._sandwich(m.rotateg(degree), a, b); // dojox.gfx.matrix.Matrix2D |
||
| 359 | } |
||
| 360 | |||
| 361 | // branch
|
||
| 362 | // degree: Number: an angle of rotation in degrees (>0 for CCW)
|
||
| 363 | // a: dojox.gfx.Point: a central point
|
||
| 364 | // b: null
|
||
| 365 | return m._sandwich(m.rotateg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D |
||
| 366 | }, |
||
| 367 | skewXAt: function(angle, a, b){ |
||
| 368 | // summary: skews a picture along the x axis using a specified point as a center of skewing
|
||
| 369 | // description: Compare with dojox.gfx.matrix.skewX().
|
||
| 370 | // angle: Number: an skewing angle in radians
|
||
| 371 | // a: Number: an x component of a central point
|
||
| 372 | // b: Number: a y component of a central point
|
||
| 373 | |||
| 374 | // accepts several signatures:
|
||
| 375 | // 1) skew angle in radians, Point
|
||
| 376 | // 2) skew angle in radians, x, y
|
||
| 377 | |||
| 378 | if(arguments.length > 2){ |
||
| 379 | return m._sandwich(m.skewX(angle), a, b); // dojox.gfx.matrix.Matrix2D |
||
| 380 | } |
||
| 381 | |||
| 382 | // branch
|
||
| 383 | // angle: Number: an skewing angle in radians
|
||
| 384 | // a: dojox.gfx.Point: a central point
|
||
| 385 | // b: null
|
||
| 386 | return m._sandwich(m.skewX(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D |
||
| 387 | }, |
||
| 388 | skewXgAt: function(degree, a, b){ |
||
| 389 | // summary: skews a picture along the x axis using a specified point as a center of skewing
|
||
| 390 | // description: Compare with dojox.gfx.matrix.skewXg().
|
||
| 391 | // degree: Number: an skewing angle in degrees
|
||
| 392 | // a: Number: an x component of a central point
|
||
| 393 | // b: Number: a y component of a central point
|
||
| 394 | |||
| 395 | // accepts several signatures:
|
||
| 396 | // 1) skew angle in degrees, Point
|
||
| 397 | // 2) skew angle in degrees, x, y
|
||
| 398 | |||
| 399 | if(arguments.length > 2){ |
||
| 400 | return m._sandwich(m.skewXg(degree), a, b); // dojox.gfx.matrix.Matrix2D |
||
| 401 | } |
||
| 402 | |||
| 403 | // branch
|
||
| 404 | // degree: Number: an skewing angle in degrees
|
||
| 405 | // a: dojox.gfx.Point: a central point
|
||
| 406 | // b: null
|
||
| 407 | return m._sandwich(m.skewXg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D |
||
| 408 | }, |
||
| 409 | skewYAt: function(angle, a, b){ |
||
| 410 | // summary: skews a picture along the y axis using a specified point as a center of skewing
|
||
| 411 | // description: Compare with dojox.gfx.matrix.skewY().
|
||
| 412 | // angle: Number: an skewing angle in radians
|
||
| 413 | // a: Number: an x component of a central point
|
||
| 414 | // b: Number: a y component of a central point
|
||
| 415 | |||
| 416 | // accepts several signatures:
|
||
| 417 | // 1) skew angle in radians, Point
|
||
| 418 | // 2) skew angle in radians, x, y
|
||
| 419 | |||
| 420 | if(arguments.length > 2){ |
||
| 421 | return m._sandwich(m.skewY(angle), a, b); // dojox.gfx.matrix.Matrix2D |
||
| 422 | } |
||
| 423 | |||
| 424 | // branch
|
||
| 425 | // angle: Number: an skewing angle in radians
|
||
| 426 | // a: dojox.gfx.Point: a central point
|
||
| 427 | // b: null
|
||
| 428 | return m._sandwich(m.skewY(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D |
||
| 429 | }, |
||
| 430 | skewYgAt: function(/* Number */ degree, /* Number||Point */ a, /* Number, optional */ b){ |
||
| 431 | // summary: skews a picture along the y axis using a specified point as a center of skewing
|
||
| 432 | // description: Compare with dojox.gfx.matrix.skewYg().
|
||
| 433 | // degree: Number: an skewing angle in degrees
|
||
| 434 | // a: Number: an x component of a central point
|
||
| 435 | // b: Number: a y component of a central point
|
||
| 436 | |||
| 437 | // accepts several signatures:
|
||
| 438 | // 1) skew angle in degrees, Point
|
||
| 439 | // 2) skew angle in degrees, x, y
|
||
| 440 | |||
| 441 | if(arguments.length > 2){ |
||
| 442 | return m._sandwich(m.skewYg(degree), a, b); // dojox.gfx.matrix.Matrix2D |
||
| 443 | } |
||
| 444 | |||
| 445 | // branch
|
||
| 446 | // degree: Number: an skewing angle in degrees
|
||
| 447 | // a: dojox.gfx.Point: a central point
|
||
| 448 | // b: null
|
||
| 449 | return m._sandwich(m.skewYg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D |
||
| 450 | } |
||
| 451 | |||
| 452 | //TODO: rect-to-rect mapping, scale-to-fit (isotropic and anisotropic versions)
|
||
| 453 | |||
| 454 | }); |
||
| 455 | })(); |
||
| 456 | |||
| 457 | // propagate Matrix2D up
|
||
| 458 | dojox.gfx.Matrix2D = dojox.gfx.matrix.Matrix2D; |
||
| 459 | |||
| 460 | } |
||
| 461 | |||
| 462 | if(!dojo._hasResource["dojox.gfx._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
||
| 463 | dojo._hasResource["dojox.gfx._base"] = true; |
||
| 464 | dojo.provide("dojox.gfx._base");
|
||
| 465 | |||
| 466 | (function(){
|
||
| 467 | var g = dojox.gfx, b = g._base;
|
||
| 468 | |||
| 469 | // candidates for dojox.style (work on VML and SVG nodes)
|
||
| 470 | g._hasClass = function(/*DomNode*/node, /*String*/classStr){ |
||
| 471 | // summary:
|
||
| 472 | // Returns whether or not the specified classes are a portion of the
|
||
| 473 | // class list currently applied to the node.
|
||
| 474 | // return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className) // Boolean
|
||
| 475 | var cls = node.getAttribute("className"); |
||
| 476 | return cls && (" " + cls + " ").indexOf(" " + classStr + " ") >= 0; // Boolean |
||
| 477 | } |
||
| 478 | g._addClass = function(/*DomNode*/node, /*String*/classStr){ |
||
| 479 | // summary:
|
||
| 480 | // Adds the specified classes to the end of the class list on the
|
||
| 481 | // passed node.
|
||
| 482 | var cls = node.getAttribute("className") || ""; |
||
| 483 | if(!cls || (" " + cls + " ").indexOf(" " + classStr + " ") < 0){ |
||
| 484 | node.setAttribute("className", cls + (cls ? " " : "") + classStr); |
||
| 485 | } |
||
| 486 | } |
||
| 487 | g._removeClass = function(/*DomNode*/node, /*String*/classStr){ |
||
| 488 | // summary: Removes classes from node.
|
||
| 489 | var cls = node.getAttribute("className"); |
||
| 490 | if(cls){
|
||
| 491 | node.setAttribute( |
||
| 492 | "className",
|
||
| 493 | cls.replace(new RegExp('(^|\\s+)' + classStr + '(\\s+|$)'), "$1$2") |
||
| 494 | ); |
||
| 495 | } |
||
| 496 | } |
||
| 497 | |||
| 498 | // candidate for dojox.html.metrics (dynamic font resize handler is not implemented here)
|
||
| 499 | |||
| 500 | // derived from Morris John's emResized measurer
|
||
| 501 | b._getFontMeasurements = function(){ |
||
| 502 | // summary:
|
||
| 503 | // Returns an object that has pixel equivilents of standard font
|
||
| 504 | // size values.
|
||
| 505 | var heights = {
|
||
| 506 | '1em': 0, '1ex': 0, '100%': 0, '12pt': 0, '16px': 0, 'xx-small': 0, |
||
| 507 | 'x-small': 0, 'small': 0, 'medium': 0, 'large': 0, 'x-large': 0, |
||
| 508 | 'xx-large': 0 |
||
| 509 | }; |
||
| 510 | |||
| 511 | if(dojo.isIE){
|
||
| 512 | // we do a font-size fix if and only if one isn't applied already.
|
||
| 513 | // NOTE: If someone set the fontSize on the HTML Element, this will kill it.
|
||
| 514 | dojo.doc.documentElement.style.fontSize="100%";
|
||
| 515 | } |
||
| 516 | |||
| 517 | // set up the measuring node.
|
||
| 518 | var div = dojo.doc.createElement("div"); |
||
| 519 | var s = div.style;
|
||
| 520 | s.position = "absolute";
|
||
| 521 | s.left = "-100px";
|
||
| 522 | s.top = "0px";
|
||
| 523 | s.width = "30px";
|
||
| 524 | s.height = "1000em";
|
||
| 525 | s.borderWidth = "0px";
|
||
| 526 | s.margin = "0px";
|
||
| 527 | s.padding = "0px";
|
||
| 528 | s.outline = "none";
|
||
| 529 | s.lineHeight = "1";
|
||
| 530 | s.overflow = "hidden";
|
||
| 531 | dojo.body().appendChild(div); |
||
| 532 | |||
| 533 | // do the measurements.
|
||
| 534 | for(var p in heights){ |
||
| 535 | div.style.fontSize = p; |
||
| 536 | heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000; |
||
| 537 | } |
||
| 538 | |||
| 539 | dojo.body().removeChild(div); |
||
| 540 | div = null;
|
||
| 541 | return heights; // object |
||
| 542 | }; |
||
| 543 | |||
| 544 | var fontMeasurements = null; |
||
| 545 | |||
| 546 | b._getCachedFontMeasurements = function(recalculate){ |
||
| 547 | if(recalculate || !fontMeasurements){
|
||
| 548 | fontMeasurements = b._getFontMeasurements(); |
||
| 549 | } |
||
| 550 | return fontMeasurements;
|
||
| 551 | }; |
||
| 552 | |||
| 553 | // candidate for dojox.html.metrics
|
||
| 554 | |||
| 555 | var measuringNode = null, empty = {}; |
||
| 556 | b._getTextBox = function( /*String*/ text, |
||
| 557 | /*Object*/ style,
|
||
| 558 | /*String?*/ className){
|
||
| 559 | var m, s, al = arguments.length; |
||
| 560 | if(!measuringNode){
|
||
| 561 | m = measuringNode = dojo.doc.createElement("div");
|
||
| 562 | s = m.style; |
||
| 563 | s.position = "absolute";
|
||
| 564 | s.left = "-10000px";
|
||
| 565 | s.top = "0";
|
||
| 566 | dojo.body().appendChild(m); |
||
| 567 | }else{
|
||
| 568 | m = measuringNode; |
||
| 569 | s = m.style; |
||
| 570 | } |
||
| 571 | // reset styles
|
||
| 572 | m.className = "";
|
||
| 573 | s.borderWidth = "0";
|
||
| 574 | s.margin = "0";
|
||
| 575 | s.padding = "0";
|
||
| 576 | s.outline = "0";
|
||
| 577 | // set new style
|
||
| 578 | if(al > 1 && style){ |
||
| 579 | for(var i in style){ |
||
| 580 | if(i in empty){ continue; } |
||
| 581 | s[i] = style[i]; |
||
| 582 | } |
||
| 583 | } |
||
| 584 | // set classes
|
||
| 585 | if(al > 2 && className){ |
||
| 586 | m.className = className; |
||
| 587 | } |
||
| 588 | // take a measure
|
||
| 589 | m.innerHTML = text; |
||
| 590 | |||
| 591 | if(m["getBoundingClientRect"]){ |
||
| 592 | var bcr = m.getBoundingClientRect();
|
||
| 593 | return {l: bcr.left, t: bcr.top, w: bcr.width || (bcr.right - bcr.left), h: bcr.height || (bcr.bottom - bcr.top)}; |
||
| 594 | }else{
|
||
| 595 | return dojo.marginBox(m);
|
||
| 596 | } |
||
| 597 | }; |
||
| 598 | |||
| 599 | // candidate for dojo.dom
|
||
| 600 | |||
| 601 | var uniqueId = 0; |
||
| 602 | b._getUniqueId = function(){ |
||
| 603 | // summary: returns a unique string for use with any DOM element
|
||
| 604 | var id;
|
||
| 605 | do{
|
||
| 606 | id = dojo._scopeName + "Unique" + (++uniqueId);
|
||
| 607 | }while(dojo.byId(id));
|
||
| 608 | return id;
|
||
| 609 | }; |
||
| 610 | })(); |
||
| 611 | |||
| 612 | dojo.mixin(dojox.gfx, {
|
||
| 613 | // summary:
|
||
| 614 | // defines constants, prototypes, and utility functions
|
||
| 615 | |||
| 616 | // default shapes, which are used to fill in missing parameters
|
||
| 617 | defaultPath: {
|
||
| 618 | type: "path", path: "" |
||
| 619 | }, |
||
| 620 | defaultPolyline: {
|
||
| 621 | type: "polyline", points: [] |
||
| 622 | }, |
||
| 623 | defaultRect: {
|
||
| 624 | type: "rect", x: 0, y: 0, width: 100, height: 100, r: 0 |
||
| 625 | }, |
||
| 626 | defaultEllipse: {
|
||
| 627 | type: "ellipse", cx: 0, cy: 0, rx: 200, ry: 100 |
||
| 628 | }, |
||
| 629 | defaultCircle: {
|
||
| 630 | type: "circle", cx: 0, cy: 0, r: 100 |
||
| 631 | }, |
||
| 632 | defaultLine: {
|
||
| 633 | type: "line", x1: 0, y1: 0, x2: 100, y2: 100 |
||
| 634 | }, |
||
| 635 | defaultImage: {
|
||
| 636 | type: "image", x: 0, y: 0, width: 0, height: 0, src: "" |
||
| 637 | }, |
||
| 638 | defaultText: {
|
||
| 639 | type: "text", x: 0, y: 0, text: "", align: "start", |
||
| 640 | decoration: "none", rotated: false, kerning: true |
||
| 641 | }, |
||
| 642 | defaultTextPath: {
|
||
| 643 | type: "textpath", text: "", align: "start", |
||
| 644 | decoration: "none", rotated: false, kerning: true |
||
| 645 | }, |
||
| 646 | |||
| 647 | // default geometric attributes
|
||
| 648 | defaultStroke: {
|
||
| 649 | type: "stroke", color: "black", style: "solid", width: 1, |
||
| 650 | cap: "butt", join: 4 |
||
| 651 | }, |
||
| 652 | defaultLinearGradient: {
|
||
| 653 | type: "linear", x1: 0, y1: 0, x2: 100, y2: 100, |
||
| 654 | colors: [
|
||
| 655 | { offset: 0, color: "black" }, { offset: 1, color: "white" }
|
||
| 656 | ] |
||
| 657 | }, |
||
| 658 | defaultRadialGradient: {
|
||
| 659 | type: "radial", cx: 0, cy: 0, r: 100, |
||
| 660 | colors: [
|
||
| 661 | { offset: 0, color: "black" }, { offset: 1, color: "white" }
|
||
| 662 | ] |
||
| 663 | }, |
||
| 664 | defaultPattern: {
|
||
| 665 | type: "pattern", x: 0, y: 0, width: 0, height: 0, src: "" |
||
| 666 | }, |
||
| 667 | defaultFont: {
|
||
| 668 | type: "font", style: "normal", variant: "normal", |
||
| 669 | weight: "normal", size: "10pt", family: "serif" |
||
| 670 | }, |
||
| 671 | |||
| 672 | getDefault: (function(){ |
||
| 673 | var typeCtorCache = {};
|
||
| 674 | // a memoized delegate()
|
||
| 675 | return function(/*String*/ type){ |
||
| 676 | var t = typeCtorCache[type];
|
||
| 677 | if(t){
|
||
| 678 | return new t(); |
||
| 679 | } |
||
| 680 | t = typeCtorCache[type] = new Function;
|
||
| 681 | t.prototype = dojox.gfx[ "default" + type ];
|
||
| 682 | return new t(); |
||
| 683 | } |
||
| 684 | })(), |
||
| 685 | |||
| 686 | normalizeColor: function(/*Color*/ color){ |
||
| 687 | // summary:
|
||
| 688 | // converts any legal color representation to normalized
|
||
| 689 | // dojo.Color object
|
||
| 690 | return (color instanceof dojo.Color) ? color : new dojo.Color(color); // dojo.Color |
||
| 691 | }, |
||
| 692 | normalizeParameters: function(existed, update){ |
||
| 693 | // summary:
|
||
| 694 | // updates an existing object with properties from an "update"
|
||
| 695 | // object
|
||
| 696 | // existed: Object
|
||
| 697 | // the "target" object to be updated
|
||
| 698 | // update: Object
|
||
| 699 | // the "update" object, whose properties will be used to update
|
||
| 700 | // the existed object
|
||
| 701 | if(update){
|
||
| 702 | var empty = {};
|
||
| 703 | for(var x in existed){ |
||
| 704 | if(x in update && !(x in empty)){ |
||
| 705 | existed[x] = update[x]; |
||
| 706 | } |
||
| 707 | } |
||
| 708 | } |
||
| 709 | return existed; // Object |
||
| 710 | }, |
||
| 711 | makeParameters: function(defaults, update){ |
||
| 712 | // summary:
|
||
| 713 | // copies the original object, and all copied properties from the
|
||
| 714 | // "update" object
|
||
| 715 | // defaults: Object
|
||
| 716 | // the object to be cloned before updating
|
||
| 717 | // update: Object
|
||
| 718 | // the object, which properties are to be cloned during updating
|
||
| 719 | if(!update){
|
||
| 720 | // return dojo.clone(defaults);
|
||
| 721 | return dojo.delegate(defaults);
|
||
| 722 | } |
||
| 723 | var result = {};
|
||
| 724 | for(var i in defaults){ |
||
| 725 | if(!(i in result)){ |
||
| 726 | result[i] = dojo.clone((i in update) ? update[i] : defaults[i]);
|
||
| 727 | } |
||
| 728 | } |
||
| 729 | return result; // Object |
||
| 730 | }, |
||
| 731 | formatNumber: function(x, addSpace){ |
||
| 732 | // summary: converts a number to a string using a fixed notation
|
||
| 733 | // x: Number: number to be converted
|
||
| 734 | // addSpace: Boolean?: if it is true, add a space before a positive number
|
||
| 735 | var val = x.toString();
|
||
| 736 | if(val.indexOf("e") >= 0){ |
||
| 737 | val = x.toFixed(4);
|
||
| 738 | }else{
|
||
| 739 | var point = val.indexOf("."); |
||
| 740 | if(point >= 0 && val.length - point > 5){ |
||
| 741 | val = x.toFixed(4);
|
||
| 742 | } |
||
| 743 | } |
||
| 744 | if(x < 0){ |
||
| 745 | return val; // String |
||
| 746 | } |
||
| 747 | return addSpace ? " " + val : val; // String |
||
| 748 | }, |
||
| 749 | // font operations
|
||
| 750 | makeFontString: function(font){ |
||
| 751 | // summary: converts a font object to a CSS font string
|
||
| 752 | // font: Object: font object (see dojox.gfx.defaultFont)
|
||
| 753 | return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object |
||
| 754 | }, |
||
| 755 | splitFontString: function(str){ |
||
| 756 | // summary:
|
||
| 757 | // converts a CSS font string to a font object
|
||
| 758 | // description:
|
||
| 759 | // Converts a CSS font string to a gfx font object. The CSS font
|
||
| 760 | // string components should follow the W3C specified order
|
||
| 761 | // (see http://www.w3.org/TR/CSS2/fonts.html#font-shorthand):
|
||
| 762 | // style, variant, weight, size, optional line height (will be
|
||
| 763 | // ignored), and family.
|
||
| 764 | // str: String
|
||
| 765 | // a CSS font string
|
||
| 766 | var font = dojox.gfx.getDefault("Font"); |
||
| 767 | var t = str.split(/\s+/); |
||
| 768 | do{
|
||
| 769 | if(t.length < 5){ break; } |
||
| 770 | font.style = t[0];
|
||
| 771 | font.variant = t[1];
|
||
| 772 | font.weight = t[2];
|
||
| 773 | var i = t[3].indexOf("/"); |
||
| 774 | font.size = i < 0 ? t[3] : t[3].substring(0, i); |
||
| 775 | var j = 4; |
||
| 776 | if(i < 0){ |
||
| 777 | if(t[4] == "/"){ |
||
| 778 | j = 6;
|
||
| 779 | }else if(t[4].charAt(0) == "/"){ |
||
| 780 | j = 5;
|
||
| 781 | } |
||
| 782 | } |
||
| 783 | if(j < t.length){
|
||
| 784 | font.family = t.slice(j).join(" ");
|
||
| 785 | } |
||
| 786 | }while(false); |
||
| 787 | return font; // Object |
||
| 788 | }, |
||
| 789 | // length operations
|
||
| 790 | cm_in_pt: 72 / 2.54, // Number: points per centimeter |
||
| 791 | mm_in_pt: 7.2 / 2.54, // Number: points per millimeter |
||
| 792 | px_in_pt: function(){ |
||
| 793 | // summary: returns a number of pixels per point
|
||
| 794 | return dojox.gfx._base._getCachedFontMeasurements()["12pt"] / 12; // Number |
||
| 795 | }, |
||
| 796 | pt2px: function(len){ |
||
| 797 | // summary: converts points to pixels
|
||
| 798 | // len: Number: a value in points
|
||
| 799 | return len * dojox.gfx.px_in_pt(); // Number |
||
| 800 | }, |
||
| 801 | px2pt: function(len){ |
||
| 802 | // summary: converts pixels to points
|
||
| 803 | // len: Number: a value in pixels
|
||
| 804 | return len / dojox.gfx.px_in_pt(); // Number |
||
| 805 | }, |
||
| 806 | normalizedLength: function(len) { |
||
| 807 | // summary: converts any length value to pixels
|
||
| 808 | // len: String: a length, e.g., "12pc"
|
||
| 809 | if(len.length == 0) return 0; |
||
| 810 | if(len.length > 2){ |
||
| 811 | var px_in_pt = dojox.gfx.px_in_pt();
|
||
| 812 | var val = parseFloat(len);
|
||
| 813 | switch(len.slice(-2)){ |
||
| 814 | case "px": return val; |
||
| 815 | case "pt": return val * px_in_pt; |
||
| 816 | case "in": return val * 72 * px_in_pt; |
||
| 817 | case "pc": return val * 12 * px_in_pt; |
||
| 818 | case "mm": return val * dojox.gfx.mm_in_pt * px_in_pt; |
||
| 819 | case "cm": return val * dojox.gfx.cm_in_pt * px_in_pt; |
||
| 820 | } |
||
| 821 | } |
||
| 822 | return parseFloat(len); // Number |
||
| 823 | }, |
||
| 824 | |||
| 825 | // a constant used to split a SVG/VML path into primitive components
|
||
| 826 | pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g, |
||
| 827 | pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g, |
||
| 828 | |||
| 829 | equalSources: function(a, b){ |
||
| 830 | // summary: compares event sources, returns true if they are equal
|
||
| 831 | return a && b && a == b;
|
||
| 832 | } |
||
| 833 | }); |
||
| 834 | |||
| 835 | } |
||
| 836 | |||
| 837 | if(!dojo._hasResource["dojox.gfx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
||
| 838 | dojo._hasResource["dojox.gfx"] = true; |
||
| 839 | dojo.provide("dojox.gfx");
|
||
| 840 | |||
| 841 | |||
| 842 | |||
| 843 | |||
| 844 | dojo.loadInit(function(){
|
||
| 845 | //Since loaderInit can be fired before any dojo.provide/require calls,
|
||
| 846 | //make sure the dojox.gfx object exists and only run this logic if dojox.gfx.renderer
|
||
| 847 | //has not been defined yet.
|
||
| 848 | var gfx = dojo.getObject("dojox.gfx", true), sl, flag, match; |
||
| 849 | if(!gfx.renderer){
|
||
| 850 | //Have a way to force a GFX renderer, if so desired.
|
||
| 851 | //Useful for being able to serialize GFX data in a particular format.
|
||
| 852 | if(dojo.config.forceGfxRenderer){
|
||
| 853 | dojox.gfx.renderer = dojo.config.forceGfxRenderer; |
||
| 854 | return;
|
||
| 855 | } |
||
| 856 | var renderers = (typeof dojo.config.gfxRenderer == "string" ? |
||
| 857 | dojo.config.gfxRenderer : "svg,vml,silverlight,canvas").split(","); |
||
| 858 | |||
| 859 | // mobile platform detection
|
||
| 860 | // TODO: move to the base?
|
||
| 861 | |||
| 862 | var ua = navigator.userAgent, iPhoneOsBuild = 0, androidVersion = 0; |
||
| 863 | if(dojo.isSafari >= 3){ |
||
| 864 | // detect mobile version of WebKit starting with "version 3"
|
||
| 865 | |||
| 866 | // comprehensive iPhone test. Have to figure out whether it's SVG or Canvas based on the build.
|
||
| 867 | // iPhone OS build numbers from en.wikipedia.org.
|
||
| 868 | if(ua.indexOf("iPhone") >= 0 || ua.indexOf("iPod") >= 0){ |
||
| 869 | // grab the build out of this. Expression is a little nasty because we want
|
||
| 870 | // to be sure we have the whole version string.
|
||
| 871 | match = ua.match(/Version\/(\d(\.\d)?(\.\d)?)\sMobile\/([^\s]*)\s?/);
|
||
| 872 | if(match){
|
||
| 873 | // grab the build out of the match. Only use the first three because of specific builds.
|
||
| 874 | iPhoneOsBuild = parseInt(match[4].substr(0,3), 16); |
||
| 875 | } |
||
| 876 | } |
||
| 877 | } |
||
| 878 | if(dojo.isWebKit){
|
||
| 879 | // Android detection
|
||
| 880 | if(!iPhoneOsBuild){
|
||
| 881 | match = ua.match(/Android\s+(\d+\.\d+)/);
|
||
| 882 | if(match){
|
||
| 883 | androidVersion = parseFloat(match[1]);
|
||
| 884 | // Android 1.0-1.1 doesn't support SVG but supports Canvas
|
||
| 885 | } |
||
| 886 | } |
||
| 887 | } |
||
| 888 | |||
| 889 | for(var i = 0; i < renderers.length; ++i){ |
||
| 890 | switch(renderers[i]){
|
||
| 891 | case "svg": |
||
| 892 | // iPhone OS builds greater than 5F1 should have SVG.
|
||
| 893 | if(!dojo.isIE && (!iPhoneOsBuild || iPhoneOsBuild >= 0x5f1) && !androidVersion && !dojo.isAIR){ |
||
| 894 | dojox.gfx.renderer = "svg";
|
||
| 895 | } |
||
| 896 | break;
|
||
| 897 | case "vml": |
||
| 898 | if(dojo.isIE){
|
||
| 899 | dojox.gfx.renderer = "vml";
|
||
| 900 | } |
||
| 901 | break;
|
||
| 902 | case "silverlight": |
||
| 903 | try{
|
||
| 904 | if(dojo.isIE){
|
||
| 905 | sl = new ActiveXObject("AgControl.AgControl"); |
||
| 906 | if(sl && sl.IsVersionSupported("1.0")){ |
||
| 907 | flag = true;
|
||
| 908 | } |
||
| 909 | }else{
|
||
| 910 | if(navigator.plugins["Silverlight Plug-In"]){ |
||
| 911 | flag = true;
|
||
| 912 | } |
||
| 913 | } |
||
| 914 | }catch(e){
|
||
| 915 | flag = false;
|
||
| 916 | }finally{
|
||
| 917 | sl = null;
|
||
| 918 | } |
||
| 919 | if(flag){ dojox.gfx.renderer = "silverlight"; } |
||
| 920 | break;
|
||
| 921 | case "canvas": |
||
| 922 | //TODO: need more comprehensive test for Canvas
|
||
| 923 | if(!dojo.isIE){
|
||
| 924 | dojox.gfx.renderer = "canvas";
|
||
| 925 | } |
||
| 926 | break;
|
||
| 927 | } |
||
| 928 | if(dojox.gfx.renderer){ break; } |
||
| 929 | } |
||
| 930 | if(dojo.config.isDebug){
|
||
| 931 | console.log("gfx renderer = " + dojox.gfx.renderer);
|
||
| 932 | } |
||
| 933 | } |
||
| 934 | }); |
||
| 935 | |||
| 936 | // include a renderer conditionally
|
||
| 937 | dojo.requireIf(dojox.gfx.renderer == "svg", "dojox.gfx.svg"); |
||
| 938 | dojo.requireIf(dojox.gfx.renderer == "vml", "dojox.gfx.vml"); |
||
| 939 | dojo.requireIf(dojox.gfx.renderer == "silverlight", "dojox.gfx.silverlight"); |
||
| 940 | dojo.requireIf(dojox.gfx.renderer == "canvas", "dojox.gfx.canvas"); |
||
| 941 | |||
| 942 | } |