_base.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. if (!dojo._hasResource["dojox.gfx._base"]) { // _hasResource checks added by
  2. // build. Do not use
  3. // _hasResource directly in your
  4. // code.
  5. dojo._hasResource["dojox.gfx._base"] = true;
  6. dojo.provide("dojox.gfx._base");
  7. // candidates for dojox.style (work on VML and SVG nodes)
  8. dojox.gfx._hasClass = function(/* DomNode */node, /* String */classStr) {
  9. // summary:
  10. // Returns whether or not the specified classes are a portion of the
  11. // class list currently applied to the node.
  12. // return (new
  13. // RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className) //
  14. // Boolean
  15. return ((" " + node.getAttribute("className") + " ").indexOf(" "
  16. + classStr + " ") >= 0); // Boolean
  17. }
  18. dojox.gfx._addClass = function(/* DomNode */node, /* String */classStr) {
  19. // summary:
  20. // Adds the specified classes to the end of the class list on the
  21. // passed node.
  22. var cls = node.getAttribute("className");
  23. if ((" " + cls + " ").indexOf(" " + classStr + " ") < 0) {
  24. node.setAttribute("className", cls + (cls ? ' ' : '') + classStr);
  25. }
  26. }
  27. dojox.gfx._removeClass = function(/* DomNode */node, /* String */classStr) {
  28. // summary: Removes classes from node.
  29. node
  30. .setAttribute("className", node.getAttribute("className")
  31. .replace(
  32. new RegExp('(^|\\s+)' + classStr
  33. + '(\\s+|$)'), "$1$2"));
  34. }
  35. // candidate for dojox.html.metrics (dynamic font resize handler is not
  36. // implemented here)
  37. // derived from Morris John's emResized measurer
  38. dojox.gfx._base._getFontMeasurements = function() {
  39. // summary
  40. // Returns an object that has pixel equivilents of standard font size
  41. // values.
  42. var heights = {
  43. '1em' : 0,
  44. '1ex' : 0,
  45. '100%' : 0,
  46. '12pt' : 0,
  47. '16px' : 0,
  48. 'xx-small' : 0,
  49. 'x-small' : 0,
  50. 'small' : 0,
  51. 'medium' : 0,
  52. 'large' : 0,
  53. 'x-large' : 0,
  54. 'xx-large' : 0
  55. };
  56. if (dojo.isIE) {
  57. // we do a font-size fix if and only if one isn't applied already.
  58. // NOTE: If someone set the fontSize on the HTML Element, this will
  59. // kill it.
  60. dojo.doc.documentElement.style.fontSize = "100%";
  61. }
  62. // set up the measuring node.
  63. var div = dojo.doc.createElement("div");
  64. div.style.position = "absolute";
  65. div.style.left = "-100px";
  66. div.style.top = "0";
  67. div.style.width = "30px";
  68. div.style.height = "1000em";
  69. div.style.border = "0";
  70. div.style.margin = "0";
  71. div.style.padding = "0";
  72. div.style.outline = "0";
  73. div.style.lineHeight = "1";
  74. div.style.overflow = "hidden";
  75. dojo.body().appendChild(div);
  76. // do the measurements.
  77. for (var p in heights) {
  78. div.style.fontSize = p;
  79. heights[p] = Math.round(div.offsetHeight * 12 / 16) * 16 / 12
  80. / 1000;
  81. }
  82. dojo.body().removeChild(div);
  83. div = null;
  84. return heights; // object
  85. };
  86. dojox.gfx._base._fontMeasurements = null;
  87. dojox.gfx._base._getCachedFontMeasurements = function(recalculate) {
  88. if (recalculate || !dojox.gfx._base._fontMeasurements) {
  89. dojox.gfx._base._fontMeasurements = dojox.gfx._base
  90. ._getFontMeasurements();
  91. }
  92. return dojox.gfx._base._fontMeasurements;
  93. };
  94. // candidate for dojo.dom
  95. dojox.gfx._base._uniqueId = 0;
  96. dojox.gfx._base._getUniqueId = function() {
  97. // summary: returns a unique string for use with any DOM element
  98. var id;
  99. do {
  100. id = "dojoUnique" + (++dojox.gfx._base._uniqueId);
  101. } while (dojo.byId(id));
  102. return id;
  103. };
  104. dojo.mixin(dojox.gfx, {
  105. // summary: defines constants, prototypes, and utility functions
  106. // default shapes, which are used to fill in missing parameters
  107. defaultPath : {
  108. type : "path",
  109. path : ""
  110. },
  111. defaultPolyline : {
  112. type : "polyline",
  113. points : []
  114. },
  115. defaultRect : {
  116. type : "rect",
  117. x : 0,
  118. y : 0,
  119. width : 100,
  120. height : 100,
  121. r : 0
  122. },
  123. defaultEllipse : {
  124. type : "ellipse",
  125. cx : 0,
  126. cy : 0,
  127. rx : 200,
  128. ry : 100
  129. },
  130. defaultCircle : {
  131. type : "circle",
  132. cx : 0,
  133. cy : 0,
  134. r : 100
  135. },
  136. defaultLine : {
  137. type : "line",
  138. x1 : 0,
  139. y1 : 0,
  140. x2 : 100,
  141. y2 : 100
  142. },
  143. defaultImage : {
  144. type : "image",
  145. x : 0,
  146. y : 0,
  147. width : 0,
  148. height : 0,
  149. src : ""
  150. },
  151. defaultText : {
  152. type : "text",
  153. x : 0,
  154. y : 0,
  155. text : "",
  156. align : "start",
  157. decoration : "none",
  158. rotated : false,
  159. kerning : true
  160. },
  161. defaultTextPath : {
  162. type : "textpath",
  163. text : "",
  164. align : "start",
  165. decoration : "none",
  166. rotated : false,
  167. kerning : true
  168. },
  169. // default geometric attributes
  170. defaultStroke : {
  171. type : "stroke",
  172. color : "black",
  173. style : "solid",
  174. width : 1,
  175. cap : "butt",
  176. join : 4
  177. },
  178. defaultLinearGradient : {
  179. type : "linear",
  180. x1 : 0,
  181. y1 : 0,
  182. x2 : 100,
  183. y2 : 100,
  184. colors : [{
  185. offset : 0,
  186. color : "black"
  187. }, {
  188. offset : 1,
  189. color : "white"
  190. }]
  191. },
  192. defaultRadialGradient : {
  193. type : "radial",
  194. cx : 0,
  195. cy : 0,
  196. r : 100,
  197. colors : [{
  198. offset : 0,
  199. color : "black"
  200. }, {
  201. offset : 1,
  202. color : "white"
  203. }]
  204. },
  205. defaultPattern : {
  206. type : "pattern",
  207. x : 0,
  208. y : 0,
  209. width : 0,
  210. height : 0,
  211. src : ""
  212. },
  213. defaultFont : {
  214. type : "font",
  215. style : "normal",
  216. variant : "normal",
  217. weight : "normal",
  218. size : "10pt",
  219. family : "serif"
  220. },
  221. normalizeColor : function(/* Color */color) {
  222. // summary: converts any legal color representation to normalized
  223. // dojo.Color object
  224. return (color instanceof dojo.Color)
  225. ? color
  226. : new dojo.Color(color); // dojo.Color
  227. },
  228. normalizeParameters : function(existed, update) {
  229. // summary: updates an existing object with properties from an
  230. // "update" object
  231. // existed: Object: the "target" object to be updated
  232. // update: Object: the "update" object, whose properties will be
  233. // used to update the existed object
  234. if (update) {
  235. var empty = {};
  236. for (var x in existed) {
  237. if (x in update && !(x in empty)) {
  238. existed[x] = update[x];
  239. }
  240. }
  241. }
  242. return existed; // Object
  243. },
  244. makeParameters : function(defaults, update) {
  245. // summary: copies the original object, and all copied properties
  246. // from the "update" object
  247. // defaults: Object: the object to be cloned before updating
  248. // update: Object: the object, which properties are to be cloned
  249. // during updating
  250. if (!update)
  251. return dojo.clone(defaults);
  252. var result = {};
  253. for (var i in defaults) {
  254. if (!(i in result)) {
  255. result[i] = dojo.clone((i in update)
  256. ? update[i]
  257. : defaults[i]);
  258. }
  259. }
  260. return result; // Object
  261. },
  262. formatNumber : function(x, addSpace) {
  263. // summary: converts a number to a string using a fixed notation
  264. // x: Number: number to be converted
  265. // addSpace: Boolean?: if it is true, add a space before a positive
  266. // number
  267. var val = x.toString();
  268. if (val.indexOf("e") >= 0) {
  269. val = x.toFixed(4);
  270. } else {
  271. var point = val.indexOf(".");
  272. if (point >= 0 && val.length - point > 5) {
  273. val = x.toFixed(4);
  274. }
  275. }
  276. if (x < 0) {
  277. return val; // String
  278. }
  279. return addSpace ? " " + val : val; // String
  280. },
  281. // font operations
  282. makeFontString : function(font) {
  283. // summary: converts a font object to a CSS font string
  284. // font: Object: font object (see dojox.gfx.defaultFont)
  285. return font.style + " " + font.variant + " " + font.weight + " "
  286. + font.size + " " + font.family; // Object
  287. },
  288. splitFontString : function(str) {
  289. // summary: converts a CSS font string to a font object
  290. // str: String: a CSS font string
  291. var font = dojo.clone(dojox.gfx.defaultFont);
  292. var t = str.split(/\s+/);
  293. do {
  294. if (t.length < 5) {
  295. break;
  296. }
  297. font.style = t[0];
  298. font.varian = t[1];
  299. font.weight = t[2];
  300. var i = t[3].indexOf("/");
  301. font.size = i < 0 ? t[3] : t[3].substring(0, i);
  302. var j = 4;
  303. if (i < 0) {
  304. if (t[4] == "/") {
  305. j = 6;
  306. break;
  307. }
  308. if (t[4].substr(0, 1) == "/") {
  309. j = 5;
  310. break;
  311. }
  312. }
  313. if (j + 3 > t.length) {
  314. break;
  315. }
  316. font.size = t[j];
  317. font.family = t[j + 1];
  318. } while (false);
  319. return font; // Object
  320. },
  321. // length operations
  322. cm_in_pt : 72 / 2.54, // Number: centimeters per inch
  323. mm_in_pt : 7.2 / 2.54, // Number: millimeters per inch
  324. px_in_pt : function() {
  325. // summary: returns a number of pixels per point
  326. return dojox.gfx._base._getCachedFontMeasurements()["12pt"] / 12; // Number
  327. },
  328. pt2px : function(len) {
  329. // summary: converts points to pixels
  330. // len: Number: a value in points
  331. return len * dojox.gfx.px_in_pt(); // Number
  332. },
  333. px2pt : function(len) {
  334. // summary: converts pixels to points
  335. // len: Number: a value in pixels
  336. return len / dojox.gfx.px_in_pt(); // Number
  337. },
  338. normalizedLength : function(len) {
  339. // summary: converts any length value to pixels
  340. // len: String: a length, e.g., "12pc"
  341. if (len.length == 0)
  342. return 0;
  343. if (len.length > 2) {
  344. var px_in_pt = dojox.gfx.px_in_pt();
  345. var val = parseFloat(len);
  346. switch (len.slice(-2)) {
  347. case "px" :
  348. return val;
  349. case "pt" :
  350. return val * px_in_pt;
  351. case "in" :
  352. return val * 72 * px_in_pt;
  353. case "pc" :
  354. return val * 12 * px_in_pt;
  355. case "mm" :
  356. return val / dojox.gfx.mm_in_pt * px_in_pt;
  357. case "cm" :
  358. return val / dojox.gfx.cm_in_pt * px_in_pt;
  359. }
  360. }
  361. return parseFloat(len); // Number
  362. },
  363. // a constant used to split a SVG/VML path into primitive components
  364. pathVmlRegExp : /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
  365. pathSvgRegExp : /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
  366. equalSources : function(a, b) {
  367. // summary: compares event sources, returns true if they are equal
  368. return a && b && a == b;
  369. }
  370. });
  371. }