shape.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. /*
  2. Copyright (c) 2004-2012, 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. if(!dojo._hasResource["dojox.gfx.shape"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.gfx.shape"] = true;
  8. dojo.provide("dojox.gfx.shape");
  9. dojo.require("dojox.gfx._base");
  10. dojo.declare("dojox.gfx.shape.Shape", null, {
  11. // summary: a Shape object, which knows how to apply
  12. // graphical attributes and transformations
  13. constructor: function(){
  14. // rawNode: Node: underlying node
  15. this.rawNode = null;
  16. // shape: Object: an abstract shape object
  17. // (see dojox.gfx.defaultPath,
  18. // dojox.gfx.defaultPolyline,
  19. // dojox.gfx.defaultRect,
  20. // dojox.gfx.defaultEllipse,
  21. // dojox.gfx.defaultCircle,
  22. // dojox.gfx.defaultLine,
  23. // or dojox.gfx.defaultImage)
  24. this.shape = null;
  25. // matrix: dojox.gfx.Matrix2D: a transformation matrix
  26. this.matrix = null;
  27. // fillStyle: Object: a fill object
  28. // (see dojox.gfx.defaultLinearGradient,
  29. // dojox.gfx.defaultRadialGradient,
  30. // dojox.gfx.defaultPattern,
  31. // or dojo.Color)
  32. this.fillStyle = null;
  33. // strokeStyle: Object: a stroke object
  34. // (see dojox.gfx.defaultStroke)
  35. this.strokeStyle = null;
  36. // bbox: dojox.gfx.Rectangle: a bounding box of this shape
  37. // (see dojox.gfx.defaultRect)
  38. this.bbox = null;
  39. // virtual group structure
  40. // parent: Object: a parent or null
  41. // (see dojox.gfx.Surface,
  42. // dojox.gfx.shape.VirtualGroup,
  43. // or dojox.gfx.Group)
  44. this.parent = null;
  45. // parentMatrix: dojox.gfx.Matrix2D
  46. // a transformation matrix inherited from the parent
  47. this.parentMatrix = null;
  48. },
  49. // trivial getters
  50. getNode: function(){
  51. // summary: returns the current DOM Node or null
  52. return this.rawNode; // Node
  53. },
  54. getShape: function(){
  55. // summary: returns the current shape object or null
  56. // (see dojox.gfx.defaultPath,
  57. // dojox.gfx.defaultPolyline,
  58. // dojox.gfx.defaultRect,
  59. // dojox.gfx.defaultEllipse,
  60. // dojox.gfx.defaultCircle,
  61. // dojox.gfx.defaultLine,
  62. // or dojox.gfx.defaultImage)
  63. return this.shape; // Object
  64. },
  65. getTransform: function(){
  66. // summary: returns the current transformation matrix or null
  67. return this.matrix; // dojox.gfx.Matrix2D
  68. },
  69. getFill: function(){
  70. // summary: returns the current fill object or null
  71. // (see dojox.gfx.defaultLinearGradient,
  72. // dojox.gfx.defaultRadialGradient,
  73. // dojox.gfx.defaultPattern,
  74. // or dojo.Color)
  75. return this.fillStyle; // Object
  76. },
  77. getStroke: function(){
  78. // summary: returns the current stroke object or null
  79. // (see dojox.gfx.defaultStroke)
  80. return this.strokeStyle; // Object
  81. },
  82. getParent: function(){
  83. // summary: returns the parent or null
  84. // (see dojox.gfx.Surface,
  85. // dojox.gfx.shape.VirtualGroup,
  86. // or dojox.gfx.Group)
  87. return this.parent; // Object
  88. },
  89. getBoundingBox: function(){
  90. // summary: returns the bounding box or null
  91. // (see dojox.gfx.defaultRect)
  92. return this.bbox; // dojox.gfx.Rectangle
  93. },
  94. getTransformedBoundingBox: function(){
  95. // summary: returns an array of four points or null
  96. // four points represent four corners of the untransformed bounding box
  97. var b = this.getBoundingBox();
  98. if(!b){
  99. return null; // null
  100. }
  101. var m = this._getRealMatrix();
  102. gm = dojox.gfx.matrix;
  103. return [ // Array
  104. gm.multiplyPoint(m, b.x, b.y),
  105. gm.multiplyPoint(m, b.x + b.width, b.y),
  106. gm.multiplyPoint(m, b.x + b.width, b.y + b.height),
  107. gm.multiplyPoint(m, b.x, b.y + b.height)
  108. ];
  109. },
  110. getEventSource: function(){
  111. // summary: returns a Node, which is used as
  112. // a source of events for this shape
  113. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  114. return this.rawNode; // Node
  115. },
  116. // empty settings
  117. setShape: function(shape){
  118. // summary: sets a shape object
  119. // (the default implementation simply ignores it)
  120. // shape: Object: a shape object
  121. // (see dojox.gfx.defaultPath,
  122. // dojox.gfx.defaultPolyline,
  123. // dojox.gfx.defaultRect,
  124. // dojox.gfx.defaultEllipse,
  125. // dojox.gfx.defaultCircle,
  126. // dojox.gfx.defaultLine,
  127. // or dojox.gfx.defaultImage)
  128. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  129. this.shape = dojox.gfx.makeParameters(this.shape, shape);
  130. this.bbox = null;
  131. return this; // self
  132. },
  133. setFill: function(fill){
  134. // summary: sets a fill object
  135. // (the default implementation simply ignores it)
  136. // fill: Object: a fill object
  137. // (see dojox.gfx.defaultLinearGradient,
  138. // dojox.gfx.defaultRadialGradient,
  139. // dojox.gfx.defaultPattern,
  140. // or dojo.Color)
  141. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  142. if(!fill){
  143. // don't fill
  144. this.fillStyle = null;
  145. return this; // self
  146. }
  147. var f = null;
  148. if(typeof(fill) == "object" && "type" in fill){
  149. // gradient or pattern
  150. switch(fill.type){
  151. case "linear":
  152. f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
  153. break;
  154. case "radial":
  155. f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
  156. break;
  157. case "pattern":
  158. f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill);
  159. break;
  160. }
  161. }else{
  162. // color object
  163. f = dojox.gfx.normalizeColor(fill);
  164. }
  165. this.fillStyle = f;
  166. return this; // self
  167. },
  168. setStroke: function(stroke){
  169. // summary: sets a stroke object
  170. // (the default implementation simply ignores it)
  171. // stroke: Object: a stroke object
  172. // (see dojox.gfx.defaultStroke)
  173. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  174. if(!stroke){
  175. // don't stroke
  176. this.strokeStyle = null;
  177. return this; // self
  178. }
  179. // normalize the stroke
  180. if(typeof stroke == "string" || dojo.isArray(stroke) || stroke instanceof dojo.Color){
  181. stroke = {color: stroke};
  182. }
  183. var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
  184. s.color = dojox.gfx.normalizeColor(s.color);
  185. return this; // self
  186. },
  187. setTransform: function(matrix){
  188. // summary: sets a transformation matrix
  189. // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
  190. // (see an argument of dojox.gfx.Matrix2D
  191. // constructor for a list of acceptable arguments)
  192. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  193. this.matrix = dojox.gfx.matrix.clone(matrix ? dojox.gfx.matrix.normalize(matrix) : dojox.gfx.matrix.identity);
  194. return this._applyTransform(); // self
  195. },
  196. _applyTransform: function(){
  197. // summary: physically sets a matrix
  198. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  199. return this; // self
  200. },
  201. // z-index
  202. moveToFront: function(){
  203. // summary: moves a shape to front of its parent's list of shapes
  204. var p = this.getParent();
  205. if(p){
  206. p._moveChildToFront(this);
  207. this._moveToFront(); // execute renderer-specific action
  208. }
  209. return this; // self
  210. },
  211. moveToBack: function(){
  212. // summary: moves a shape to back of its parent's list of shapes
  213. var p = this.getParent();
  214. if(p){
  215. p._moveChildToBack(this);
  216. this._moveToBack(); // execute renderer-specific action
  217. }
  218. return this;
  219. },
  220. _moveToFront: function(){
  221. // summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront()
  222. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  223. },
  224. _moveToBack: function(){
  225. // summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront()
  226. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  227. },
  228. // apply left & right transformation
  229. applyRightTransform: function(matrix){
  230. // summary: multiplies the existing matrix with an argument on right side
  231. // (this.matrix * matrix)
  232. // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
  233. // (see an argument of dojox.gfx.Matrix2D
  234. // constructor for a list of acceptable arguments)
  235. return matrix ? this.setTransform([this.matrix, matrix]) : this; // self
  236. },
  237. applyLeftTransform: function(matrix){
  238. // summary: multiplies the existing matrix with an argument on left side
  239. // (matrix * this.matrix)
  240. // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
  241. // (see an argument of dojox.gfx.Matrix2D
  242. // constructor for a list of acceptable arguments)
  243. return matrix ? this.setTransform([matrix, this.matrix]) : this; // self
  244. },
  245. applyTransform: function(matrix){
  246. // summary: a shortcut for dojox.gfx.Shape.applyRightTransform
  247. // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object
  248. // (see an argument of dojox.gfx.Matrix2D
  249. // constructor for a list of acceptable arguments)
  250. return matrix ? this.setTransform([this.matrix, matrix]) : this; // self
  251. },
  252. // virtual group methods
  253. removeShape: function(silently){
  254. // summary: removes the shape from its parent's list of shapes
  255. // silently: Boolean?: if true, do not redraw a picture yet
  256. if(this.parent){
  257. this.parent.remove(this, silently);
  258. }
  259. return this; // self
  260. },
  261. _setParent: function(parent, matrix){
  262. // summary: sets a parent
  263. // parent: Object: a parent or null
  264. // (see dojox.gfx.Surface,
  265. // dojox.gfx.shape.VirtualGroup,
  266. // or dojox.gfx.Group)
  267. // matrix: dojox.gfx.Matrix2D:
  268. // a 2D matrix or a matrix-like object
  269. this.parent = parent;
  270. return this._updateParentMatrix(matrix); // self
  271. },
  272. _updateParentMatrix: function(matrix){
  273. // summary: updates the parent matrix with new matrix
  274. // matrix: dojox.gfx.Matrix2D:
  275. // a 2D matrix or a matrix-like object
  276. this.parentMatrix = matrix ? dojox.gfx.matrix.clone(matrix) : null;
  277. return this._applyTransform(); // self
  278. },
  279. _getRealMatrix: function(){
  280. // summary: returns the cumulative ("real") transformation matrix
  281. // by combining the shape's matrix with its parent's matrix
  282. var m = this.matrix;
  283. var p = this.parent;
  284. while(p){
  285. if(p.matrix){
  286. m = dojox.gfx.matrix.multiply(p.matrix, m);
  287. }
  288. p = p.parent;
  289. }
  290. return m; // dojox.gfx.Matrix2D
  291. }
  292. });
  293. dojox.gfx.shape._eventsProcessing = {
  294. connect: function(name, object, method){
  295. // summary: connects a handler to an event on this shape
  296. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  297. return arguments.length > 2 ? // Object
  298. dojo.connect(this.getEventSource(), name, object, method) :
  299. dojo.connect(this.getEventSource(), name, object);
  300. },
  301. disconnect: function(token){
  302. // summary: connects a handler by token from an event on this shape
  303. // COULD BE RE-IMPLEMENTED BY THE RENDERER!
  304. dojo.disconnect(token);
  305. }
  306. };
  307. dojo.extend(dojox.gfx.shape.Shape, dojox.gfx.shape._eventsProcessing);
  308. dojox.gfx.shape.Container = {
  309. // summary: a container of shapes, which can be used
  310. // as a foundation for renderer-specific groups, or as a way
  311. // to logically group shapes (e.g, to propagate matricies)
  312. _init: function() {
  313. // children: Array: a list of children
  314. this.children = [];
  315. },
  316. // group management
  317. openBatch: function() {
  318. // summary: starts a new batch, subsequent new child shapes will be held in
  319. // the batch instead of appending to the container directly
  320. },
  321. closeBatch: function() {
  322. // summary: submits the current batch, append all pending child shapes to DOM
  323. },
  324. add: function(shape){
  325. // summary: adds a shape to the list
  326. // shape: dojox.gfx.Shape: a shape
  327. var oldParent = shape.getParent();
  328. if(oldParent){
  329. oldParent.remove(shape, true);
  330. }
  331. this.children.push(shape);
  332. return shape._setParent(this, this._getRealMatrix()); // self
  333. },
  334. remove: function(shape, silently){
  335. // summary: removes a shape from the list
  336. // silently: Boolean?: if true, do not redraw a picture yet
  337. for(var i = 0; i < this.children.length; ++i){
  338. if(this.children[i] == shape){
  339. if(silently){
  340. // skip for now
  341. }else{
  342. shape.parent = null;
  343. shape.parentMatrix = null;
  344. }
  345. this.children.splice(i, 1);
  346. break;
  347. }
  348. }
  349. return this; // self
  350. },
  351. clear: function(){
  352. // summary: removes all shapes from a group/surface
  353. this.children = [];
  354. return this; // self
  355. },
  356. // moving child nodes
  357. _moveChildToFront: function(shape){
  358. // summary: moves a shape to front of the list of shapes
  359. for(var i = 0; i < this.children.length; ++i){
  360. if(this.children[i] == shape){
  361. this.children.splice(i, 1);
  362. this.children.push(shape);
  363. break;
  364. }
  365. }
  366. return this; // self
  367. },
  368. _moveChildToBack: function(shape){
  369. // summary: moves a shape to back of the list of shapes
  370. for(var i = 0; i < this.children.length; ++i){
  371. if(this.children[i] == shape){
  372. this.children.splice(i, 1);
  373. this.children.unshift(shape);
  374. break;
  375. }
  376. }
  377. return this; // self
  378. }
  379. };
  380. dojo.declare("dojox.gfx.shape.Surface", null, {
  381. // summary: a surface object to be used for drawings
  382. constructor: function(){
  383. // underlying node
  384. this.rawNode = null;
  385. // the parent node
  386. this._parent = null;
  387. // the list of DOM nodes to be deleted in the case of destruction
  388. this._nodes = [];
  389. // the list of events to be detached in the case of destruction
  390. this._events = [];
  391. },
  392. destroy: function(){
  393. // summary: destroy all relevant external resources and release all
  394. // external references to make this object garbage-collectible
  395. dojo.forEach(this._nodes, dojo.destroy);
  396. this._nodes = [];
  397. dojo.forEach(this._events, dojo.disconnect);
  398. this._events = [];
  399. this.rawNode = null; // recycle it in _nodes, if it needs to be recycled
  400. if(dojo.isIE){
  401. while(this._parent.lastChild){
  402. dojo.destroy(this._parent.lastChild);
  403. }
  404. }else{
  405. this._parent.innerHTML = "";
  406. }
  407. this._parent = null;
  408. },
  409. getEventSource: function(){
  410. // summary: returns a node, which can be used to attach event listeners
  411. return this.rawNode; // Node
  412. },
  413. _getRealMatrix: function(){
  414. // summary: always returns the identity matrix
  415. return null; // dojox.gfx.Matrix2D
  416. },
  417. isLoaded: true,
  418. onLoad: function(/*dojox.gfx.Surface*/ surface){
  419. // summary: local event, fired once when the surface is created
  420. // asynchronously, used only when isLoaded is false, required
  421. // only for Silverlight.
  422. },
  423. whenLoaded: function(
  424. /*Object?*/ context,
  425. /*Function|String*/ method
  426. ){
  427. var f = dojo.hitch(context, method);
  428. if(this.isLoaded){
  429. f(this);
  430. }else{
  431. var h = dojo.connect(this, "onLoad", function(surface){
  432. dojo.disconnect(h);
  433. f(surface);
  434. });
  435. }
  436. }
  437. });
  438. dojo.extend(dojox.gfx.shape.Surface, dojox.gfx.shape._eventsProcessing);
  439. dojo.declare("dojox.gfx.Point", null, {
  440. // summary: a hypothetical 2D point to be used for drawings - {x, y}
  441. // description: This object is defined for documentation purposes.
  442. // You should use the naked object instead: {x: 1, y: 2}.
  443. });
  444. dojo.declare("dojox.gfx.Rectangle", null, {
  445. // summary: a hypothetical rectangle - {x, y, width, height}
  446. // description: This object is defined for documentation purposes.
  447. // You should use the naked object instead: {x: 1, y: 2, width: 100, height: 200}.
  448. });
  449. dojo.declare("dojox.gfx.shape.Rect", dojox.gfx.shape.Shape, {
  450. // summary: a generic rectangle
  451. constructor: function(rawNode){
  452. // rawNode: Node: a DOM Node
  453. this.shape = dojox.gfx.getDefault("Rect");
  454. this.rawNode = rawNode;
  455. },
  456. getBoundingBox: function(){
  457. // summary: returns the bounding box (its shape in this case)
  458. return this.shape; // dojox.gfx.Rectangle
  459. }
  460. });
  461. dojo.declare("dojox.gfx.shape.Ellipse", dojox.gfx.shape.Shape, {
  462. // summary: a generic ellipse
  463. constructor: function(rawNode){
  464. // rawNode: Node: a DOM Node
  465. this.shape = dojox.gfx.getDefault("Ellipse");
  466. this.rawNode = rawNode;
  467. },
  468. getBoundingBox: function(){
  469. // summary: returns the bounding box
  470. if(!this.bbox){
  471. var shape = this.shape;
  472. this.bbox = {x: shape.cx - shape.rx, y: shape.cy - shape.ry,
  473. width: 2 * shape.rx, height: 2 * shape.ry};
  474. }
  475. return this.bbox; // dojox.gfx.Rectangle
  476. }
  477. });
  478. dojo.declare("dojox.gfx.shape.Circle", dojox.gfx.shape.Shape, {
  479. // summary: a generic circle
  480. // (this is a helper object, which is defined for convenience)
  481. constructor: function(rawNode){
  482. // rawNode: Node: a DOM Node
  483. this.shape = dojox.gfx.getDefault("Circle");
  484. this.rawNode = rawNode;
  485. },
  486. getBoundingBox: function(){
  487. // summary: returns the bounding box
  488. if(!this.bbox){
  489. var shape = this.shape;
  490. this.bbox = {x: shape.cx - shape.r, y: shape.cy - shape.r,
  491. width: 2 * shape.r, height: 2 * shape.r};
  492. }
  493. return this.bbox; // dojox.gfx.Rectangle
  494. }
  495. });
  496. dojo.declare("dojox.gfx.shape.Line", dojox.gfx.shape.Shape, {
  497. // summary: a generic line
  498. // (this is a helper object, which is defined for convenience)
  499. constructor: function(rawNode){
  500. // rawNode: Node: a DOM Node
  501. this.shape = dojox.gfx.getDefault("Line");
  502. this.rawNode = rawNode;
  503. },
  504. getBoundingBox: function(){
  505. // summary: returns the bounding box
  506. if(!this.bbox){
  507. var shape = this.shape;
  508. this.bbox = {
  509. x: Math.min(shape.x1, shape.x2),
  510. y: Math.min(shape.y1, shape.y2),
  511. width: Math.abs(shape.x2 - shape.x1),
  512. height: Math.abs(shape.y2 - shape.y1)
  513. };
  514. }
  515. return this.bbox; // dojox.gfx.Rectangle
  516. }
  517. });
  518. dojo.declare("dojox.gfx.shape.Polyline", dojox.gfx.shape.Shape, {
  519. // summary: a generic polyline/polygon
  520. // (this is a helper object, which is defined for convenience)
  521. constructor: function(rawNode){
  522. // rawNode: Node: a DOM Node
  523. this.shape = dojox.gfx.getDefault("Polyline");
  524. this.rawNode = rawNode;
  525. },
  526. setShape: function(points, closed){
  527. // summary: sets a polyline/polygon shape object
  528. // points: Object: a polyline/polygon shape object
  529. // closed: Boolean: close the polyline to make a polygon
  530. if(points && points instanceof Array){
  531. // points: Array: an array of points
  532. this.inherited(arguments, [{points: points}]);
  533. if(closed && this.shape.points.length){
  534. this.shape.points.push(this.shape.points[0]);
  535. }
  536. }else{
  537. this.inherited(arguments, [points]);
  538. }
  539. return this; // self
  540. },
  541. _normalizePoints: function(){
  542. // summary: normalize points to array of {x:number, y:number}
  543. var p = this.shape.points, l = p && p.length;
  544. if(l && typeof p[0] == "number"){
  545. var points = [];
  546. for(var i = 0; i < l; i += 2){
  547. points.push({x: p[i], y: p[i + 1]});
  548. }
  549. this.shape.points = points;
  550. }
  551. },
  552. getBoundingBox: function(){
  553. // summary: returns the bounding box
  554. if(!this.bbox && this.shape.points.length){
  555. var p = this.shape.points;
  556. var l = p.length;
  557. var t = p[0];
  558. var bbox = {l: t.x, t: t.y, r: t.x, b: t.y};
  559. for(var i = 1; i < l; ++i){
  560. t = p[i];
  561. if(bbox.l > t.x) bbox.l = t.x;
  562. if(bbox.r < t.x) bbox.r = t.x;
  563. if(bbox.t > t.y) bbox.t = t.y;
  564. if(bbox.b < t.y) bbox.b = t.y;
  565. }
  566. this.bbox = {
  567. x: bbox.l,
  568. y: bbox.t,
  569. width: bbox.r - bbox.l,
  570. height: bbox.b - bbox.t
  571. };
  572. }
  573. return this.bbox; // dojox.gfx.Rectangle
  574. }
  575. });
  576. dojo.declare("dojox.gfx.shape.Image", dojox.gfx.shape.Shape, {
  577. // summary: a generic image
  578. // (this is a helper object, which is defined for convenience)
  579. constructor: function(rawNode){
  580. // rawNode: Node: a DOM Node
  581. this.shape = dojox.gfx.getDefault("Image");
  582. this.rawNode = rawNode;
  583. },
  584. getBoundingBox: function(){
  585. // summary: returns the bounding box (its shape in this case)
  586. return this.shape; // dojox.gfx.Rectangle
  587. },
  588. setStroke: function(){
  589. // summary: ignore setting a stroke style
  590. return this; // self
  591. },
  592. setFill: function(){
  593. // summary: ignore setting a fill style
  594. return this; // self
  595. }
  596. });
  597. dojo.declare("dojox.gfx.shape.Text", dojox.gfx.shape.Shape, {
  598. // summary: a generic text
  599. constructor: function(rawNode){
  600. // rawNode: Node: a DOM Node
  601. this.fontStyle = null;
  602. this.shape = dojox.gfx.getDefault("Text");
  603. this.rawNode = rawNode;
  604. },
  605. getFont: function(){
  606. // summary: returns the current font object or null
  607. return this.fontStyle; // Object
  608. },
  609. setFont: function(newFont){
  610. // summary: sets a font for text
  611. // newFont: Object: a font object (see dojox.gfx.defaultFont) or a font string
  612. this.fontStyle = typeof newFont == "string" ? dojox.gfx.splitFontString(newFont) :
  613. dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont);
  614. this._setFont();
  615. return this; // self
  616. }
  617. });
  618. dojox.gfx.shape.Creator = {
  619. // summary: shape creators
  620. createShape: function(shape){
  621. // summary: creates a shape object based on its type; it is meant to be used
  622. // by group-like objects
  623. // shape: Object: a shape descriptor object
  624. var gfx = dojox.gfx;
  625. switch(shape.type){
  626. case gfx.defaultPath.type: return this.createPath(shape);
  627. case gfx.defaultRect.type: return this.createRect(shape);
  628. case gfx.defaultCircle.type: return this.createCircle(shape);
  629. case gfx.defaultEllipse.type: return this.createEllipse(shape);
  630. case gfx.defaultLine.type: return this.createLine(shape);
  631. case gfx.defaultPolyline.type: return this.createPolyline(shape);
  632. case gfx.defaultImage.type: return this.createImage(shape);
  633. case gfx.defaultText.type: return this.createText(shape);
  634. case gfx.defaultTextPath.type: return this.createTextPath(shape);
  635. }
  636. return null;
  637. },
  638. createGroup: function(){
  639. // summary: creates a group shape
  640. return this.createObject(dojox.gfx.Group); // dojox.gfx.Group
  641. },
  642. createRect: function(rect){
  643. // summary: creates a rectangle shape
  644. // rect: Object: a path object (see dojox.gfx.defaultRect)
  645. return this.createObject(dojox.gfx.Rect, rect); // dojox.gfx.Rect
  646. },
  647. createEllipse: function(ellipse){
  648. // summary: creates an ellipse shape
  649. // ellipse: Object: an ellipse object (see dojox.gfx.defaultEllipse)
  650. return this.createObject(dojox.gfx.Ellipse, ellipse); // dojox.gfx.Ellipse
  651. },
  652. createCircle: function(circle){
  653. // summary: creates a circle shape
  654. // circle: Object: a circle object (see dojox.gfx.defaultCircle)
  655. return this.createObject(dojox.gfx.Circle, circle); // dojox.gfx.Circle
  656. },
  657. createLine: function(line){
  658. // summary: creates a line shape
  659. // line: Object: a line object (see dojox.gfx.defaultLine)
  660. return this.createObject(dojox.gfx.Line, line); // dojox.gfx.Line
  661. },
  662. createPolyline: function(points){
  663. // summary: creates a polyline/polygon shape
  664. // points: Object: a points object (see dojox.gfx.defaultPolyline)
  665. // or an Array of points
  666. return this.createObject(dojox.gfx.Polyline, points); // dojox.gfx.Polyline
  667. },
  668. createImage: function(image){
  669. // summary: creates a image shape
  670. // image: Object: an image object (see dojox.gfx.defaultImage)
  671. return this.createObject(dojox.gfx.Image, image); // dojox.gfx.Image
  672. },
  673. createText: function(text){
  674. // summary: creates a text shape
  675. // text: Object: a text object (see dojox.gfx.defaultText)
  676. return this.createObject(dojox.gfx.Text, text); // dojox.gfx.Text
  677. },
  678. createPath: function(path){
  679. // summary: creates a path shape
  680. // path: Object: a path object (see dojox.gfx.defaultPath)
  681. return this.createObject(dojox.gfx.Path, path); // dojox.gfx.Path
  682. },
  683. createTextPath: function(text){
  684. // summary: creates a text shape
  685. // text: Object: a textpath object (see dojox.gfx.defaultTextPath)
  686. return this.createObject(dojox.gfx.TextPath, {}).setText(text); // dojox.gfx.TextPath
  687. },
  688. createObject: function(shapeType, rawShape){
  689. // summary: creates an instance of the passed shapeType class
  690. // shapeType: Function: a class constructor to create an instance of
  691. // rawShape: Object: properties to be passed in to the classes "setShape" method
  692. // SHOULD BE RE-IMPLEMENTED BY THE RENDERER!
  693. return null; // dojox.gfx.Shape
  694. }
  695. };
  696. }