svg_attach.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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.svg_attach"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.gfx.svg_attach"] = true;
  8. dojo.provide("dojox.gfx.svg_attach");
  9. dojo.require("dojox.gfx.svg");
  10. dojo.experimental("dojox.gfx.svg_attach");
  11. (function(){
  12. var g = dojox.gfx, svg = g.svg;
  13. svg.attachNode = function(node){
  14. // summary: creates a shape from a Node
  15. // node: Node: an SVG node
  16. if(!node){
  17. return null;
  18. }
  19. var s = null;
  20. switch(node.tagName.toLowerCase()){
  21. case svg.Rect.nodeType:
  22. s = new svg.Rect(node);
  23. attachRect(s);
  24. break;
  25. case svg.Ellipse.nodeType:
  26. s = new svg.Ellipse(node);
  27. attachShape(s, g.defaultEllipse);
  28. break;
  29. case svg.Polyline.nodeType:
  30. s = new svg.Polyline(node);
  31. attachShape(s, g.defaultPolyline);
  32. break;
  33. case svg.Path.nodeType:
  34. s = new svg.Path(node);
  35. attachShape(s, g.defaultPath);
  36. break;
  37. case svg.Circle.nodeType:
  38. s = new svg.Circle(node);
  39. attachShape(s, g.defaultCircle);
  40. break;
  41. case svg.Line.nodeType:
  42. s = new svg.Line(node);
  43. attachShape(s, g.defaultLine);
  44. break;
  45. case svg.Image.nodeType:
  46. s = new svg.Image(node);
  47. attachShape(s, g.defaultImage);
  48. break;
  49. case svg.Text.nodeType:
  50. var t = node.getElementsByTagName("textPath");
  51. if(t && t.length){
  52. s = new svg.TextPath(node);
  53. attachShape(s, g.defaultPath);
  54. attachTextPath(s);
  55. }else{
  56. s = new svg.Text(node);
  57. attachText(s);
  58. }
  59. attachFont(s);
  60. break;
  61. default:
  62. //console.debug("FATAL ERROR! tagName = " + node.tagName);
  63. return null;
  64. }
  65. if(!(s instanceof svg.Image)){
  66. attachFill(s);
  67. attachStroke(s);
  68. }
  69. attachTransform(s);
  70. return s; // dojox.gfx.Shape
  71. };
  72. svg.attachSurface = function(node){
  73. // summary: creates a surface from a Node
  74. // node: Node: an SVG node
  75. var s = new svg.Surface();
  76. s.rawNode = node;
  77. var def_elems = node.getElementsByTagName("defs");
  78. if(def_elems.length == 0){
  79. return null; // dojox.gfx.Surface
  80. }
  81. s.defNode = def_elems[0];
  82. return s; // dojox.gfx.Surface
  83. };
  84. function attachFill(object){
  85. // summary: deduces a fill style from a node.
  86. // object: dojox.gfx.Shape: an SVG shape
  87. var fill = object.rawNode.getAttribute("fill");
  88. if(fill == "none"){
  89. object.fillStyle = null;
  90. return;
  91. }
  92. var fillStyle = null, gradient = svg.getRef(fill);
  93. if(gradient){
  94. switch(gradient.tagName.toLowerCase()){
  95. case "lineargradient":
  96. fillStyle = _getGradient(g.defaultLinearGradient, gradient);
  97. dojo.forEach(["x1", "y1", "x2", "y2"], function(x){
  98. fillStyle[x] = gradient.getAttribute(x);
  99. });
  100. break;
  101. case "radialgradient":
  102. fillStyle = _getGradient(g.defaultRadialGradient, gradient);
  103. dojo.forEach(["cx", "cy", "r"], function(x){
  104. fillStyle[x] = gradient.getAttribute(x);
  105. });
  106. fillStyle.cx = gradient.getAttribute("cx");
  107. fillStyle.cy = gradient.getAttribute("cy");
  108. fillStyle.r = gradient.getAttribute("r");
  109. break;
  110. case "pattern":
  111. fillStyle = dojo.clone(g.defaultPattern);
  112. dojo.forEach(["x", "y", "width", "height"], function(x){
  113. fillStyle[x] = gradient.getAttribute(x);
  114. });
  115. fillStyle.src = gradient.firstChild.getAttributeNS(svg.xmlns.xlink, "href");
  116. break;
  117. }
  118. }else{
  119. fillStyle = new dojo.Color(fill);
  120. var opacity = object.rawNode.getAttribute("fill-opacity");
  121. if(opacity != null){ fillStyle.a = opacity; }
  122. }
  123. object.fillStyle = fillStyle;
  124. }
  125. function _getGradient(defaultGradient, gradient){
  126. var fillStyle = dojo.clone(defaultGradient);
  127. fillStyle.colors = [];
  128. for(var i = 0; i < gradient.childNodes.length; ++i){
  129. fillStyle.colors.push({
  130. offset: gradient.childNodes[i].getAttribute("offset"),
  131. color: new dojo.Color(gradient.childNodes[i].getAttribute("stop-color"))
  132. });
  133. }
  134. return fillStyle;
  135. }
  136. function attachStroke(object){
  137. // summary: deduces a stroke style from a node.
  138. // object: dojox.gfx.Shape: an SVG shape
  139. var rawNode = object.rawNode, stroke = rawNode.getAttribute("stroke");
  140. if(stroke == null || stroke == "none"){
  141. object.strokeStyle = null;
  142. return;
  143. }
  144. var strokeStyle = object.strokeStyle = dojo.clone(g.defaultStroke);
  145. var color = new dojo.Color(stroke);
  146. if(color){
  147. strokeStyle.color = color;
  148. strokeStyle.color.a = rawNode.getAttribute("stroke-opacity");
  149. strokeStyle.width = rawNode.getAttribute("stroke-width");
  150. strokeStyle.cap = rawNode.getAttribute("stroke-linecap");
  151. strokeStyle.join = rawNode.getAttribute("stroke-linejoin");
  152. if(strokeStyle.join == "miter"){
  153. strokeStyle.join = rawNode.getAttribute("stroke-miterlimit");
  154. }
  155. strokeStyle.style = rawNode.getAttribute("dojoGfxStrokeStyle");
  156. }
  157. }
  158. function attachTransform(object){
  159. // summary: deduces a transformation matrix from a node.
  160. // object: dojox.gfx.Shape: an SVG shape
  161. var matrix = object.rawNode.getAttribute("transform");
  162. if(matrix.match(/^matrix\(.+\)$/)){
  163. var t = matrix.slice(7, -1).split(",");
  164. object.matrix = g.matrix.normalize({
  165. xx: parseFloat(t[0]), xy: parseFloat(t[2]),
  166. yx: parseFloat(t[1]), yy: parseFloat(t[3]),
  167. dx: parseFloat(t[4]), dy: parseFloat(t[5])
  168. });
  169. }else{
  170. object.matrix = null;
  171. }
  172. }
  173. function attachFont(object){
  174. // summary: deduces a font style from a Node.
  175. // object: dojox.gfx.Shape: an SVG shape
  176. var fontStyle = object.fontStyle = dojo.clone(g.defaultFont),
  177. r = object.rawNode;
  178. fontStyle.style = r.getAttribute("font-style");
  179. fontStyle.variant = r.getAttribute("font-variant");
  180. fontStyle.weight = r.getAttribute("font-weight");
  181. fontStyle.size = r.getAttribute("font-size");
  182. fontStyle.family = r.getAttribute("font-family");
  183. }
  184. function attachShape(object, def){
  185. // summary: builds a shape from a node.
  186. // object: dojox.gfx.Shape: an SVG shape
  187. // def: Object: a default shape template
  188. var shape = object.shape = dojo.clone(def), r = object.rawNode;
  189. for(var i in shape) {
  190. shape[i] = r.getAttribute(i);
  191. }
  192. }
  193. function attachRect(object){
  194. // summary: builds a rectangle shape from a node.
  195. // object: dojox.gfx.Shape: an SVG shape
  196. attachShape(object, g.defaultRect);
  197. object.shape.r = Math.min(object.rawNode.getAttribute("rx"), object.rawNode.getAttribute("ry"));
  198. }
  199. function attachText(object){
  200. // summary: builds a text shape from a node.
  201. // object: dojox.gfx.Shape: an SVG shape
  202. var shape = object.shape = dojo.clone(g.defaultText),
  203. r = object.rawNode;
  204. shape.x = r.getAttribute("x");
  205. shape.y = r.getAttribute("y");
  206. shape.align = r.getAttribute("text-anchor");
  207. shape.decoration = r.getAttribute("text-decoration");
  208. shape.rotated = parseFloat(r.getAttribute("rotate")) != 0;
  209. shape.kerning = r.getAttribute("kerning") == "auto";
  210. shape.text = r.firstChild.nodeValue;
  211. }
  212. function attachTextPath(object){
  213. // summary: builds a textpath shape from a node.
  214. // object: dojox.gfx.Shape: an SVG shape
  215. var shape = object.shape = dojo.clone(g.defaultTextPath),
  216. r = object.rawNode;
  217. shape.align = r.getAttribute("text-anchor");
  218. shape.decoration = r.getAttribute("text-decoration");
  219. shape.rotated = parseFloat(r.getAttribute("rotate")) != 0;
  220. shape.kerning = r.getAttribute("kerning") == "auto";
  221. shape.text = r.firstChild.nodeValue;
  222. }
  223. })();
  224. }