source: Dev/branches/rest-dojo-ui/client/dojox/gfx/vml_attach.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 10.7 KB
Line 
1define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path", "dojo/_base/Color", "./vml"],
2  function (kernel, lang, g, m, pathLib, Color, vml){
3
4        kernel.experimental("dojox.gfx.vml_attach");
5       
6        vml.attachNode = function(node){
7                // summary: creates a shape from a Node
8                // node: Node: an VML node
9                if(!node) return null;
10                var s = null;
11                switch(node.tagName.toLowerCase()){
12                        case vml.Rect.nodeType:
13                                s = new vml.Rect(node);
14                                attachRect(s);
15                                break;
16                        case vml.Ellipse.nodeType:
17                                if(node.style.width == node.style.height){
18                                        s = new vml.Circle(node);
19                                        attachCircle(s);
20                                }else{
21                                        s = new vml.Ellipse(node);
22                                        attachEllipse(s);
23                                }
24                                break;
25                        case vml.Path.nodeType:
26                                switch(node.getAttribute("dojoGfxType")){
27                                        case "line":
28                                                s = new vml.Line(node);
29                                                attachLine(s);
30                                                break;
31                                        case "polyline":
32                                                s = new vml.Polyline(node);
33                                                attachPolyline(s);
34                                                break;
35                                        case "path":
36                                                s = new vml.Path(node);
37                                                attachPath(s);
38                                                break;
39                                        case "text":
40                                                s = new vml.Text(node);
41                                                attachText(s);
42                                                attachFont(s);
43                                                attachTextTransform(s);
44                                                break;
45                                        case "textpath":
46                                                s = new vml.TextPath(node);
47                                                attachPath(s);
48                                                attachText(s);
49                                                attachFont(s);
50                                                break;
51                                }
52                                break;
53                        case vml.Image.nodeType:
54                                switch(node.getAttribute("dojoGfxType")){
55                                        case "image":
56                                                s = new vml.Image(node);
57                                                attachImage(s);
58                                                attachImageTransform(s);
59                                                break;
60                                }
61                                break;
62                        default:
63                                //console.debug("FATAL ERROR! tagName = " + node.tagName);
64                                return null;
65                }
66                if(!(s instanceof vml.Image)){
67                        attachFill(s);
68                        attachStroke(s);
69                        if(!(s instanceof vml.Text)){
70                                attachTransform(s);
71                        }
72                }
73                return s;       // dojox.gfx.Shape
74        };
75
76        vml.attachSurface = function(node){
77                // summary: creates a surface from a Node
78                // node: Node: an VML node
79                var s = new vml.Surface();
80                s.clipNode = node;
81                var r = s.rawNode = node.firstChild;
82                var b = r.firstChild;
83                if(!b || b.tagName != "rect"){
84                        return null;    // dojox.gfx.Surface
85                }
86                s.bgNode = r;
87                return s;       // dojox.gfx.Surface
88        };
89
90        var attachFill = function(object){
91                // summary: deduces a fill style from a node.
92                // object: dojox.gfx.Shape: an VML shape
93                var fillStyle = null, r = object.rawNode, fo = r.fill, stops, i, t;
94                if(fo.on && fo.type == "gradient"){
95                        fillStyle = lang.clone(g.defaultLinearGradient),
96                                rad = m._degToRad(fo.angle);
97                        fillStyle.x2 = Math.cos(rad);
98                        fillStyle.y2 = Math.sin(rad);
99                        fillStyle.colors = [];
100                        stops = fo.colors.value.split(";");
101                        for(i = 0; i < stops.length; ++i){
102                                 t = stops[i].match(/\S+/g);
103                                if(!t || t.length != 2){ continue; }
104                                fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new Color(t[1])});
105                        }
106                }else if(fo.on && fo.type == "gradientradial"){
107                        fillStyle = lang.clone(g.defaultRadialGradient),
108                                w = parseFloat(r.style.width), h = parseFloat(r.style.height);
109                        fillStyle.cx = isNaN(w) ? 0 : fo.focusposition.x * w;
110                        fillStyle.cy = isNaN(h) ? 0 : fo.focusposition.y * h;
111                        fillStyle.r  = isNaN(w) ? 1 : w / 2;
112                        fillStyle.colors = [];
113                        stops = fo.colors.value.split(";");
114                        for(i = stops.length - 1; i >= 0; --i){
115                                t = stops[i].match(/\S+/g);
116                                if(!t || t.length != 2){ continue; }
117                                fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new Color(t[1])});
118                        }
119                }else if(fo.on && fo.type == "tile"){
120                        fillStyle = lang.clone(g.defaultPattern);
121                        fillStyle.width  = g.pt2px(fo.size.x); // from pt
122                        fillStyle.height = g.pt2px(fo.size.y); // from pt
123                        fillStyle.x = fo.origin.x * fillStyle.width;
124                        fillStyle.y = fo.origin.y * fillStyle.height;
125                        fillStyle.src = fo.src;
126                }else if(fo.on && r.fillcolor){
127                        // a color object !
128                        fillStyle = new Color(r.fillcolor+"");
129                        fillStyle.a = fo.opacity;
130                }
131                object.fillStyle = fillStyle;
132        };
133
134        var attachStroke = function(object) {
135                // summary: deduces a stroke style from a node.
136                // object: dojox.gfx.Shape: an VML shape
137                var r = object.rawNode;
138                if(!r.stroked){
139                        object.strokeStyle = null;
140                        return;
141                }
142                var strokeStyle = object.strokeStyle = lang.clone(g.defaultStroke),
143                        rs = r.stroke;
144                strokeStyle.color = new Color(r.strokecolor.value);
145                strokeStyle.width = g.normalizedLength(r.strokeweight+"");
146                strokeStyle.color.a = rs.opacity;
147                strokeStyle.cap = this._translate(this._capMapReversed, rs.endcap);
148                strokeStyle.join = rs.joinstyle == "miter" ? rs.miterlimit : rs.joinstyle;
149                strokeStyle.style = rs.dashstyle;
150        };
151
152        var attachTransform = function(object) {
153                // summary: deduces a transformation matrix from a node.
154                // object: dojox.gfx.Shape: an VML shape
155                var s = object.rawNode.skew, sm = s.matrix, so = s.offset;
156                object.matrix = m.normalize({
157                        xx: sm.xtox,
158                        xy: sm.ytox,
159                        yx: sm.xtoy,
160                        yy: sm.ytoy,
161                        dx: g.pt2px(so.x),
162                        dy: g.pt2px(so.y)
163                });
164        };
165
166        var attachGroup = function(object){
167                // summary: reconstructs all group shape parameters from a node (VML).
168                // object: dojox.gfx.Shape: an VML shape
169                // attach the background
170                object.bgNode = object.rawNode.firstChild;      // TODO: check it first
171        };
172
173        var attachRect = function(object){
174                // summary: builds a rectangle shape from a node.
175                // object: dojox.gfx.Shape: an VML shape
176                // a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node
177                var r = object.rawNode, arcsize = r.outerHTML.match(/arcsize = \"(\d*\.?\d+[%f]?)\"/)[1],
178                        style = r.style, width = parseFloat(style.width), height = parseFloat(style.height);
179                arcsize = (arcsize.indexOf("%") >= 0) ? parseFloat(arcsize) / 100 : vml._parseFloat(arcsize);
180                // make an object
181                object.shape = g.makeParameters(g.defaultRect, {
182                        x: parseInt(style.left),
183                        y: parseInt(style.top),
184                        width:  width,
185                        height: height,
186                        r: Math.min(width, height) * arcsize
187                });
188        };
189
190        var attachEllipse = function(object){
191                // summary: builds an ellipse shape from a node.
192                // object: dojox.gfx.Shape: an VML shape
193                var style = object.rawNode.style,
194                        rx = parseInt(style.width ) / 2,
195                        ry = parseInt(style.height) / 2;
196                object.shape = g.makeParameters(g.defaultEllipse, {
197                        cx: parseInt(style.left) + rx,
198                        cy: parseInt(style.top ) + ry,
199                        rx: rx,
200                        ry: ry
201                });
202        };
203
204        var attachCircle = function(object){
205                // summary: builds a circle shape from a node.
206                // object: dojox.gfx.Shape: an VML shape
207                var style = object.rawNode.style, r = parseInt(style.width) / 2;
208                object.shape = g.makeParameters(g.defaultCircle, {
209                        cx: parseInt(style.left) + r,
210                        cy: parseInt(style.top)  + r,
211                        r:  r
212                });
213        };
214
215        var attachLine = function(object){
216                // summary: builds a line shape from a node.
217                // object: dojox.gfx.Shape: an VML shape
218                var shape = object.shape = lang.clone(g.defaultLine),
219                        p = object.rawNode.path.v.match(g.pathVmlRegExp);
220                do{
221                        if(p.length < 7 || p[0] != "m" || p[3] != "l" || p[6] != "e"){ break; }
222                        shape.x1 = parseInt(p[1]);
223                        shape.y1 = parseInt(p[2]);
224                        shape.x2 = parseInt(p[4]);
225                        shape.y2 = parseInt(p[5]);
226                }while(false);
227        };
228
229        var attachPolyline = function(object){
230                // summary: builds a polyline/polygon shape from a node.
231                // object: dojox.gfx.Shape: an VML shape
232                var shape = object.shape = lang.clone(g.defaultPolyline),
233                        p = object.rawNode.path.v.match(g.pathVmlRegExp);
234                do{
235                        if(p.length < 3 || p[0] != "m"){ break; }
236                        var x = parseInt(p[0]), y = parseInt(p[1]);
237                        if(isNaN(x) || isNaN(y)){ break; }
238                        shape.points.push({x: x, y: y});
239                        if(p.length < 6 || p[3] != "l"){ break; }
240                        for(var i = 4; i < p.length; i += 2){
241                                x = parseInt(p[i]);
242                                y = parseInt(p[i + 1]);
243                                if(isNaN(x) || isNaN(y)){ break; }
244                                shape.points.push({x: x, y: y});
245                        }
246                }while(false);
247        };
248
249        var attachImage = function(object){
250                // summary: builds an image shape from a node.
251                // object: dojox.gfx.Shape: an VML shape
252                object.shape = lang.clone(g.defaultImage);
253                object.shape.src = object.rawNode.firstChild.src;
254        };
255
256        var attachImageTransform = function(object) {
257                // summary: deduces a transformation matrix from a node.
258                // object: dojox.gfx.Shape: an VML shape
259                var mm = object.rawNode.filters["DXImageTransform.Microsoft.Matrix"];
260                object.matrix = m.normalize({
261                        xx: mm.M11,
262                        xy: mm.M12,
263                        yx: mm.M21,
264                        yy: mm.M22,
265                        dx: mm.Dx,
266                        dy: mm.Dy
267                });
268        };
269
270        var attachText = function(object){
271                // summary: builds a text shape from a node.
272                // object: dojox.gfx.Shape: an VML shape
273                var shape = object.shape = lang.clone(g.defaultText),
274                        r = object.rawNode, p = r.path.v.match(g.pathVmlRegExp);
275                do{
276                        if(!p || p.length != 7){ break; }
277                        var c = r.childNodes, i = 0;
278                        for(; i < c.length && c[i].tagName != "textpath"; ++i);
279                        if(i >= c.length){ break; }
280                        var s = c[i].style;
281                        shape.text = c[i].string;
282                        switch(s["v-text-align"]){
283                                case "left":
284                                        shape.x = parseInt(p[1]);
285                                        shape.align = "start";
286                                        break;
287                                case "center":
288                                        shape.x = (parseInt(p[1]) + parseInt(p[4])) / 2;
289                                        shape.align = "middle";
290                                        break;
291                                case "right":
292                                        shape.x = parseInt(p[4]);
293                                        shape.align = "end";
294                                        break;
295                        }
296                        shape.y = parseInt(p[2]);
297                        shape.decoration = s["text-decoration"];
298                        shape.rotated = s["v-rotate-letters"].toLowerCase() in vml._bool;
299                        shape.kerning = s["v-text-kern"].toLowerCase() in vml._bool;
300                        return;
301                }while(false);
302                object.shape = null;
303        };
304
305        var attachFont = function(object){
306                // summary: deduces a font style from a node.
307                // object: dojox.gfx.Shape: an VML shape
308                var fontStyle = object.fontStyle = lang.clone(g.defaultFont),
309                        c = object.rawNode.childNodes, i = 0;
310                for(; i < c.length && c[i].tagName == "textpath"; ++i);
311                if(i >= c.length){
312                        object.fontStyle = null;
313                        return;
314                }
315                var s = c[i].style;
316                fontStyle.style = s.fontstyle;
317                fontStyle.variant = s.fontvariant;
318                fontStyle.weight = s.fontweight;
319                fontStyle.size = s.fontsize;
320                fontStyle.family = s.fontfamily;
321        };
322
323        var attachTextTransform = function(object) {
324                // summary: deduces a transformation matrix from a node.
325                // object: dojox.gfx.Shape: an VML shape
326                attachTransform(object);
327                var matrix = object.matrix, fs = object.fontStyle;
328                // see comments in _getRealMatrix()
329                if(matrix && fs){
330                        object.matrix = m.multiply(matrix, {dy: g.normalizedLength(fs.size) * 0.35});
331                }
332        };
333
334        var attachPath = function(object){
335                // summary: builds a path shape from a Node.
336                // object: dojox.gfx.Shape: an VML shape
337                var shape = object.shape = lang.clone(g.defaultPath),
338                        p = object.rawNode.path.v.match(g.pathVmlRegExp),
339                        t = [], skip = false, map = pathLib._pathVmlToSvgMap;
340                for(var i = 0; i < p.length; ++p){
341                        var s = p[i];
342                        if(s in map) {
343                                skip = false;
344                                t.push(map[s]);
345                        } else if(!skip){
346                                var n = parseInt(s);
347                                if(isNaN(n)){
348                                        skip = true;
349                                }else{
350                                        t.push(n);
351                                }
352                        }
353                }
354                var l = t.length;
355                if(l >= 4 && t[l - 1] == "" && t[l - 2] == 0 && t[l - 3] == 0 && t[l - 4] == "l"){
356                        t.splice(l - 4, 4);
357                }
358                if(l){
359                        shape.path = t.join(" ");
360                }
361        };
362
363        return vml; //return augmented vml api
364});
Note: See TracBrowser for help on using the repository browser.