svg_attach.js 7.1 KB

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