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