svg_attach.js 7.4 KB

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