Mercurial > MadButterfly
annotate nodejs/svg.js @ 759:ae1ae29348d1
Add origin calculation support
author | wycc |
---|---|
date | Sat, 28 Aug 2010 22:14:38 +0800 |
parents | 199bac90b90a |
children | 77b561bb7929 |
rev | line source |
---|---|
624 | 1 var libxml = require('libxmljs'); |
2 var sys=require('sys'); | |
3 var mbfly = require("mbfly"); | |
646 | 4 var ldr = mbfly.img_ldr_new("."); |
714 | 5 |
624 | 6 |
713 | 7 var _std_colors = { |
8 "white": [1, 1, 1], | |
9 "black": [0, 0, 0], | |
10 "red": [1, 0, 0] | |
11 }; | |
12 | |
714 | 13 exports.loadSVG=function(mb_rt,root,filename) { |
718
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
14 return new loadSVG(mb_rt, root, filename); |
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
15 }; |
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
16 |
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
17 function loadSVG(mb_rt, root, filename) { |
624 | 18 var doc = libxml.parseXmlFile(filename); |
19 var nodes = doc.root().childNodes(); | |
20 var coord = mb_rt.coord_new(root); | |
21 var k; | |
759 | 22 var accu=[1,0,0,0,1,0]; |
714 | 23 this.mb_rt = mb_rt; |
750 | 24 this.stop_ref={}; |
25 this.gradients={}; | |
624 | 26 |
27 for(k in nodes) { | |
28 var n = nodes[k].name(); | |
29 if (n == "defs") { | |
714 | 30 this.parseDefs(root,nodes[k]); |
624 | 31 } else if (n == "g") { |
759 | 32 this.parseGroup(accu,root,'root_coord',nodes[k]); |
624 | 33 } |
34 } | |
35 } | |
36 | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
37 function make_mbnames(mb_rt, n, obj) { |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
38 var mbname; |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
39 var name; |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
40 |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
41 if(!mb_rt.mbnames) |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
42 mb_rt.mbnames = {}; |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
43 |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
44 mbname = n.attr("mbname"); |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
45 if(mbname) { |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
46 name = mbname.value(); |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
47 mb_rt.mbnames[name] = obj; |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
48 } |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
49 } |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
50 |
624 | 51 function getInteger(n,name) |
52 { | |
53 if (n == null) return 0; | |
54 var a = n.attr(name); | |
55 if (a==null) return 0; | |
56 return parseInt(a.value()); | |
57 } | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
58 |
631 | 59 function parsePointSize(s) |
60 { | |
61 var fs=0; | |
62 var i; | |
624 | 63 |
631 | 64 for(i=0;i<s.length;i++) { |
65 if (s[i]<'0' || s[i] > '9') break; | |
66 fs = fs*10 + (s[i]-'0'); | |
67 } | |
68 return fs; | |
69 | |
70 } | |
71 | |
72 function parseColor(c) | |
73 { | |
74 if (c[0] == '#') { | |
75 return parseInt(c.substring(1,3),16)<<16 | parseInt(c.substring(3,5),16)<<8 | parseInt(c.substring(5,7),16); | |
76 } | |
77 } | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
78 |
631 | 79 function parseTextStyle(style,n) |
624 | 80 { |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
81 var attr; |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
82 if (n) { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
83 attr = n.attr('style'); |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
84 } else { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
85 attr = null; |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
86 } |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
87 if (attr == null) { |
631 | 88 return; |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
89 } |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
90 var f = attr.value().split(';'); |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
91 |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
92 for(i in f) { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
93 var kv = f[i].split(':'); |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
94 if (kv[0] == 'font-size') { |
631 | 95 style.fs = parsePointSize(kv[1]); |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
96 } else if (kv[0] == "font-style") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
97 } else if (kv[0] == "font-weight") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
98 } else if (kv[0] == "fill") { |
631 | 99 style.color = parseColor(kv[1]); |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
100 } else if (kv[0] == "fill-opacity") { |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
101 } else if (kv[0] == "stroke-opacity") { |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
102 } else if (kv[0] == "stroke") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
103 } else if (kv[0] == "stroke-width") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
104 } else if (kv[0] == "stroke-linecap") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
105 } else if (kv[0] == "stroke-linejoin") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
106 } else if (kv[0] == "stroke-lineopacity") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
107 } else if (kv[0] == "font-family") { |
631 | 108 style.family = kv[1]; |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
109 } else if (kv[0] == "font-stretch") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
110 } else if (kv[0] == "font-variant") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
111 } else if (kv[0] == "text-anchor") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
112 } else if (kv[0] == "text-align") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
113 } else if (kv[0] == "writing-mode") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
114 } else if (kv[0] == "line-height") { |
632 | 115 } else { |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
116 sys.puts("Unknown style: "+kv[0]); |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
117 } |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
118 } |
624 | 119 } |
732
6879aa403306
Add set_text to the coordinate of the coord_t of the text.
wycc
parents:
720
diff
changeset
|
120 function tspan_set_text(text) |
6879aa403306
Add set_text to the coordinate of the coord_t of the text.
wycc
parents:
720
diff
changeset
|
121 { |
6879aa403306
Add set_text to the coordinate of the coord_t of the text.
wycc
parents:
720
diff
changeset
|
122 this.text.set_text(text); |
6879aa403306
Add set_text to the coordinate of the coord_t of the text.
wycc
parents:
720
diff
changeset
|
123 } |
624 | 124 |
718
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
125 loadSVG.prototype.parseTSpan=function(coord, n,style) |
624 | 126 { |
127 var x = getInteger(n,'x'); | |
128 var y = getInteger(n,'y'); | |
714 | 129 var tcoord = this.mb_rt.coord_new(coord); |
624 | 130 var nodes = n.childNodes(); |
131 var k; | |
132 | |
714 | 133 var obj = this.mb_rt.stext_new(n.text(),x,y); |
631 | 134 parseTextStyle(style,n); |
714 | 135 style.paint = this.mb_rt.paint_color_new(1,1,1,1); |
136 style.face=this.mb_rt.font_face_query(style.family, 2, 100); | |
631 | 137 obj.set_style([[20,style.face,style.fs]]); |
138 style.paint.fill(obj); | |
624 | 139 tcoord.add_shape(obj); |
140 for(k in nodes) { | |
141 var name = nodes[k].name(); | |
142 if (name == "tspan") { | |
714 | 143 this.parseTSpan(tcoord,nodes[k]); |
624 | 144 } else { |
145 } | |
146 } | |
732
6879aa403306
Add set_text to the coordinate of the coord_t of the text.
wycc
parents:
720
diff
changeset
|
147 tcoord.set_text=tspan_set_text; |
6879aa403306
Add set_text to the coordinate of the coord_t of the text.
wycc
parents:
720
diff
changeset
|
148 tcoord.text = obj; |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
149 make_mbnames(this.mb_rt, n, tcoord); |
624 | 150 } |
151 | |
718
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
152 loadSVG.prototype._prepare_paint_color=function(color, alpha) { |
706 | 153 var paint; |
713 | 154 var c; |
706 | 155 |
156 if (color[0]=='#') { | |
157 var r,g,b; | |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
158 r = parseInt(color.substring(1,3),16)/255; |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
159 g = parseInt(color.substring(3,5),16)/255; |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
160 b = parseInt(color.substring(5,7),16)/255; |
714 | 161 paint = this.mb_rt.paint_color_new(r, g, b, alpha); |
713 | 162 } else if(_std_colors[color]) { |
163 c = _std_colors[color]; | |
714 | 164 paint = this.mb_rt.paint_color_new(c[0], c[1], c[2], alpha); |
706 | 165 } else { |
714 | 166 paint = this.mb_rt.paint_color_new(0,0,0,1); |
706 | 167 } |
168 return paint; | |
169 } | |
170 | |
759 | 171 function guessPathBoundingBox(coord,d) |
172 { | |
173 var items = d.split(' '); | |
174 var len = items.length; | |
175 var pair; | |
176 var i; | |
177 var minx,miny; | |
178 | |
179 minx = 10000; | |
180 miny = 10000; | |
181 | |
182 for(i=0;i<len;i++) { | |
183 var type = items[i].toLowerCase(); | |
184 x = minx;y = miny; | |
185 switch(type) { | |
186 case 'm': | |
187 case 'l': | |
188 case 'a': | |
189 case 'x': | |
190 pair = items[i+1].split(','); | |
191 if (pair.length==2) { | |
192 x = parseFloat(pair[0]); | |
193 y = parseFloat(pair[1]); | |
194 i++; | |
195 } else { | |
196 x = parseFloat(items[i+1]); | |
197 y = parseFloat(items[i+2]); | |
198 i+=2; | |
199 } | |
200 break; | |
201 case 'q': | |
202 // Implement this latter | |
203 break; | |
204 case 'c': | |
205 // Implement this latter | |
206 break; | |
207 case 's': | |
208 // Implement this latter | |
209 break; | |
210 case 'h': | |
211 x = parseFloat(items[i+1]); | |
212 break; | |
213 case 'v': | |
214 y = parseFloat(items[i+1]); | |
215 break; | |
216 } | |
217 if (x < minx) minx = x; | |
218 if (y < miny) miny = y; | |
219 } | |
220 if (coord.center.x > minx) | |
221 coord.center.x = minx; | |
222 if (coord.center.y > miny) | |
223 coord.center.y = miny; | |
224 } | |
225 | |
226 | |
718
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
227 loadSVG.prototype.parsePath=function(coord,id, n) |
706 | 228 { |
229 var d = n.attr('d').value(); | |
230 var style = n.attr('style'); | |
714 | 231 var path = this.mb_rt.path_new(d); |
706 | 232 var paint; |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
233 var fill_alpha = 1; |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
234 var stroke_alpha = 1; |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
235 var fill_color; |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
236 var stroke_color; |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
237 var black_paint; |
706 | 238 |
759 | 239 guessPathBoundingBox(coord,d); |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
240 if(style != null) { |
706 | 241 var items = style.value().split(';'); |
242 var alpha; | |
243 | |
244 for(i in items) { | |
245 var f = items[i].split(':'); | |
246 if (f[0] == 'opacity') { | |
247 alpha = f[1]; | |
248 } else if (f[0] == 'fill') { | |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
249 fill_color = f[1]; |
706 | 250 } else if (f[0] == 'fill-opacity') { |
251 fill_alpha = parseFloat(f[1]); | |
252 } else if (f[0] == 'stroke') { | |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
253 stroke_color = f[1]; |
706 | 254 } else if (f[0] == 'stroke-width') { |
255 path.stroke_width = parseFloat(f[1]); | |
256 } else if (f[0] == 'stroke-opacity') { | |
257 stroke_alpha = parseFloat(f[1]); | |
258 } | |
259 } | |
260 | |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
261 } |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
262 |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
263 if(!fill_color || !stroke_color) |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
264 black_paint = this.mb_rt.paint_color_new(0, 0, 0, 1); |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
265 |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
266 if(fill_color) { |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
267 if(fill_color != "none") { |
714 | 268 paint = this._prepare_paint_color(fill_color, fill_alpha); |
706 | 269 paint.fill(path); |
759 | 270 sys.puts("paint path with "+fill_color+" "+fill_alpha); |
706 | 271 } |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
272 } else { |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
273 black_paint.fill(path); |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
274 } |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
275 if(stroke_color) { |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
276 if(stroke_color != "none") { |
714 | 277 paint = this._prepare_paint_color(stroke_color, stroke_alpha); |
706 | 278 paint.stroke(path); |
759 | 279 sys.puts("stroke path"); |
706 | 280 } |
717
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
281 } else { |
b822b1912d67
Paint with black for unspecified, not "none", fill and stroke.
Thinker K.F. Li <thinker@branda.to>
parents:
714
diff
changeset
|
282 black_paint.stroke(path); |
706 | 283 } |
284 coord.add_shape(path); | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
285 |
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
286 make_mbnames(this.mb_rt, n, path); |
706 | 287 } |
288 | |
718
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
289 loadSVG.prototype.parseText=function(coord,id, n) |
624 | 290 { |
291 var x = getInteger(n,'x'); | |
292 var y = getInteger(n,'y'); | |
714 | 293 var tcoord = this.mb_rt.coord_new(coord); |
631 | 294 var style = new Object(); |
759 | 295 |
296 if (n.attr('x')) | |
297 if (coord.center.x > x) | |
298 coord.center.x = x; | |
299 if (n.attr('y')) | |
300 if (coord.center.y > y) | |
301 coord.center.y = y; | |
631 | 302 style.fs = 20; |
303 style.family = 'courier'; | |
304 parseTextStyle(style,n); | |
624 | 305 var nodes = n.childNodes(); |
306 var k; | |
307 for(k in nodes) { | |
720
9c5abb4e114b
Fix issue of redefine a variable with the same name of a argument
Thinker K.F. Li <thinker@branda.to>
parents:
719
diff
changeset
|
308 var c= nodes[k].name(); |
9c5abb4e114b
Fix issue of redefine a variable with the same name of a argument
Thinker K.F. Li <thinker@branda.to>
parents:
719
diff
changeset
|
309 if (c == "tspan") { |
714 | 310 this.parseTSpan(tcoord,nodes[k],style); |
624 | 311 } else { |
312 } | |
313 } | |
314 | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
315 make_mbnames(this.mb_rt, n, tcoord); |
624 | 316 } |
317 | |
759 | 318 |
319 function multiply(s,d) { | |
320 var m=[]; | |
321 m[0] = s[0]*d[0]+s[1]*d[3]; | |
322 m[1] = s[0]*d[1]+s[1]*d[4]; | |
323 m[2] = s[0]*d[2]+s[1]*d[5]+s[2]; | |
324 m[3] = s[3]*d[0]+s[4]*d[3]; | |
325 m[4] = s[3]*d[1]+s[4]*d[4]; | |
326 m[5] = s[3]*d[2]+s[4]*d[5]+s[5]; | |
327 s[0] = m[0]; | |
328 s[1] = m[1]; | |
329 s[2] = m[2]; | |
330 s[3] = m[3]; | |
331 s[4] = m[4]; | |
332 s[5] = m[5]; | |
333 } | |
334 | |
624 | 335 function parseTransform(coord, s) |
336 { | |
337 var off = s.indexOf('translate'); | |
338 if (off != -1) { | |
339 var ss = s.substring(off+9); | |
340 for(i=0;i<ss.length;i++) { | |
341 if (ss[i] == '(') break; | |
342 } | |
343 ss = ss.substring(i+1); | |
344 for(i=0;i<ss.length;i++) { | |
345 if (ss[i] == ')') { | |
346 ss = ss.substring(0,i); | |
347 break; | |
348 } | |
349 } | |
350 var f = ss.split(','); | |
351 var x,y; | |
706 | 352 x = parseFloat(f[0]); |
353 y = parseFloat(f[1]); | |
759 | 354 coord[2] += x; |
355 coord[5] += y; | |
624 | 356 } |
357 off = s.indexOf('matrix'); | |
358 if (off != -1) { | |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
359 var end = s.indexOf(')'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
360 var m = s.substring(7,end); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
361 var fields = m.split(','); |
759 | 362 var newm=[]; |
363 newm[0] = parseFloat(fields[0]); | |
364 newm[1] = parseFloat(fields[2]); | |
365 newm[2] = parseFloat(fields[4]); | |
366 newm[3] = parseFloat(fields[1]); | |
367 newm[4] = parseFloat(fields[3]); | |
368 newm[5] = parseFloat(fields[5]); | |
369 multiply(coord,newm); | |
624 | 370 } |
371 } | |
372 | |
759 | 373 loadSVG.prototype.parseRect=function(accu_matrix,coord, id, n) |
624 | 374 { |
759 | 375 sys.puts("rect"); |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
376 var x = getInteger(n,'x'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
377 var y = getInteger(n,'y'); |
759 | 378 var rx,ry; |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
379 var w = getInteger(n,'width'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
380 var h = getInteger(n,'height'); |
759 | 381 var trans = n.attr('transform'); |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
382 var paint; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
383 |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
384 var style = n.attr('style'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
385 |
759 | 386 if (trans) { |
387 parseTransform(coord,trans.value()); | |
388 var m = [1,0,0,0,1,0]; | |
389 parseTransform(m,trans.value()); | |
390 rx = x+m[2]; | |
391 ry = y+m[5]; | |
392 } | |
393 | |
394 if (coord.center.x > rx) | |
395 coord.center.x = rx; | |
396 if (coord.center.y > ry) | |
397 coord.center.y = ry; | |
398 coord.center.x += accu_matrix[2]; | |
399 coord.center.y += accu_matrix[5]; | |
400 | |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
401 if (style==null) { |
714 | 402 paint = this.mb_rt.paint_color_new(0,0,0,0.1); |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
403 } else { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
404 var items = style.value().split(';'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
405 var fill = ''; |
708
ac9c20db953e
Default alpha of a tag is '1'
Thinker K.F. Li <thinker@branda.to>
parents:
706
diff
changeset
|
406 var alpha = 1; |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
407 for(i in items) { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
408 var f = items[i].split(':'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
409 if (f[0] == 'opacity') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
410 alpha = f[1]; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
411 } else if (f[0] == 'fill') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
412 fill = f[1]; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
413 } else if (f[0] == 'fill-opacity') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
414 } else if (f[0] == 'stroke') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
415 } else if (f[0] == 'stroken-width') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
416 } else if (f[0] == 'stroke-opacity') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
417 } |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
418 } |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
419 if (fill[0]=='#') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
420 var r,g,b; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
421 r = parseInt(fill.substring(1,3),16)/256; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
422 g = parseInt(fill.substring(3,5),16)/256; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
423 b = parseInt(fill.substring(5,7),16)/256; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
424 |
714 | 425 paint = this.mb_rt.paint_color_new(r,g,b,parseFloat(alpha)); |
750 | 426 } else if (fill.substring(0,3) == 'url') { |
427 var id = fill.substring(5,fill.length-1); | |
428 var gr = this.gradients[id]; | |
429 paint = this.mb_rt.paint_linear_new(gr[0],gr[1],gr[2],gr[3]); | |
430 paint.set_stops(this.stop_ref[id]); | |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
431 } else { |
714 | 432 paint = this.mb_rt.paint_color_new(0,0,0,1); |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
433 } |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
434 } |
714 | 435 var rect = this.mb_rt.rect_new(x,y,w,h,10, 10); |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
436 paint.fill(rect); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
437 coord.add_shape(rect); |
624 | 438 } |
439 | |
759 | 440 loadSVG.prototype.parseGroup=function(accu_matrix,root, group_id, n) |
624 | 441 { |
442 var k; | |
443 var nodes = n.childNodes(); | |
714 | 444 var coord = this.mb_rt.coord_new(root); |
624 | 445 // Parse the transform and style here |
446 var trans = n.attr('transform'); | |
759 | 447 var accu=[1,0,0,0,1,0]; |
448 coord.center= new Object(); | |
449 coord.center.x = 10000; | |
450 coord.center.y = 10000; | |
624 | 451 if (trans!=null) { |
452 parseTransform(coord, trans.value()); | |
759 | 453 } |
454 accu[2] = accu_matrix[2]+coord[2]; | |
455 accu[5] = accu_matrix[5]+coord[5]; | |
456 | |
624 | 457 |
458 for(k in nodes) { | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
459 var c = nodes[k].name(); |
624 | 460 var attr = nodes[k].attr('id'); |
461 var id; | |
462 if (attr) { | |
463 id = attr.value(); | |
464 } | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
465 if (c == "g") { |
759 | 466 this.parseGroup(accu,coord, id, nodes[k]); |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
467 } else if (c == "path") { |
714 | 468 this.parsePath(coord, id, nodes[k]); |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
469 } else if (c == "text") { |
714 | 470 this.parseText(coord, id, nodes[k]); |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
471 } else if (c == "rect") { |
759 | 472 this.parseRect(accu_matrix,coord, id, nodes[k]); |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
473 } else if (c == "image") { |
714 | 474 this.parseImage(coord, id, nodes[k]); |
624 | 475 } |
476 } | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
477 make_mbnames(this.mb_rt, n, coord); |
624 | 478 } |
479 | |
718
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
480 loadSVG.prototype.parseImage=function(coord,id, n) |
646 | 481 { |
482 var ref = n.attr('href').value(); | |
483 | |
484 if (ref == null) return; | |
647 | 485 if (ref.substr(0,7) == "file://") { |
486 ref = ref.substring(7); | |
487 } else if (ref.substr(0,5)=="file:") { | |
488 ref = ref.substring(5); | |
489 } else { | |
646 | 490 return; |
491 } | |
492 var w; | |
493 var h; | |
494 var x,y; | |
495 | |
496 w = n.attr("width"); | |
497 if (w == null) return; | |
759 | 498 w = parseFloat(w.value()); |
646 | 499 h = n.attr("height"); |
500 if (h == null) return; | |
759 | 501 h = parseFloat(h.value()); |
646 | 502 x = n.attr("x"); |
503 if (x == null) return; | |
759 | 504 x = parseFloat(x.value()); |
646 | 505 y = n.attr("y"); |
506 if (y == null) return; | |
759 | 507 y = parseFloat(y.value()); |
508 if (coord.center.x > x) | |
509 coord.center.x = x; | |
510 if (coord.center.y > y) | |
511 coord.center.y = y; | |
714 | 512 var img = this.mb_rt.image_new(x,y,w,h); |
646 | 513 var img_data = ldr.load(ref); |
714 | 514 var paint = this.mb_rt.paint_image_new(img_data); |
646 | 515 paint.fill(img); |
516 coord.add_shape(img); | |
719
1b6856fda760
Collect mbnames and mapping to object through mb_rt.mbnames
Thinker K.F. Li <thinker@branda.to>
parents:
718
diff
changeset
|
517 make_mbnames(this.mb_rt, n, img); |
646 | 518 } |
624 | 519 |
750 | 520 loadSVG.prototype._MB_parseLinearGradient=function(root,n) |
521 { | |
522 var id = n.attr('id'); | |
523 var k; | |
524 var nodes = n.childNodes(); | |
525 | |
526 if (id == null) return; | |
527 var x1 = n.attr("x1"); | |
528 var y1 = n.attr("y1"); | |
529 var x2 = n.attr("x2"); | |
530 var y2 = n.attr("y2"); | |
531 var gr; | |
532 var color, opacity; | |
533 var stops; | |
534 var r,g,b; | |
535 stops=[]; | |
536 for(k in nodes) { | |
537 var ss = nodes[k]; | |
538 if (ss.name()=="stop") { | |
539 var style = ss.attr("style").value(); | |
540 var items = style.split(';'); | |
541 var off = parseInt(ss.attr('offset').value()); | |
542 color = 'black'; | |
543 opacity = 1; | |
544 for (i in items) { | |
545 it = items[i]; | |
546 var f = it.split(':'); | |
547 k = f[0]; | |
548 v = f[1]; | |
549 if (k == 'stop-color') { | |
550 color = v.substring(1); | |
551 if (v == 'white') { | |
552 r = 1; | |
553 g = 1; | |
554 b = 1; | |
555 } else if (v == 'black') { | |
556 r = 0; | |
557 g = 0; | |
558 b = 0; | |
559 } else { | |
560 r = parseInt(color.substring(0,2),16)/255.0; | |
561 g = parseInt(color.substring(2,4),16)/255.0; | |
562 b = parseInt(color.substring(4,6),16)/255.0; | |
563 } | |
564 } else if (k=='stop-opacity') { | |
565 opacity = parseFloat(v); | |
566 } | |
567 } | |
568 stops.push([off, r,g,b,opacity]); | |
569 } | |
570 } | |
571 var href = n.attr('href'); | |
572 if (href != null) { | |
573 href = href.value(); | |
574 pstops = this.stop_ref[href.substring(1)]; | |
575 stops = pstops.concat(stops); | |
576 } | |
577 id = id.value(); | |
578 this.stop_ref[id] = stops; | |
579 if (x1) | |
580 x1 = parseFloat(x1.value()); | |
581 if (x2) | |
582 x2 = parseFloat(x2.value()); | |
583 if (y1) | |
584 y1 = parseFloat(y1.value()); | |
585 if (y2) | |
586 y2 = parseFloat(y2.value()); | |
587 this.gradients[id] = [x1,y1,x2,y2]; | |
588 } | |
589 | |
718
0cd59ce76e67
Refactor loadSVG as a class
Thinker K.F. Li <thinker@branda.to>
parents:
717
diff
changeset
|
590 loadSVG.prototype.parseDefs=function(root,n) |
624 | 591 { |
592 var k; | |
593 var nodes = n.childNodes(); | |
594 | |
595 for(k in nodes) { | |
596 var name = nodes[k].name(); | |
597 if (name == "linearGradient") { | |
750 | 598 this._MB_parseLinearGradient(root,nodes[k]); |
624 | 599 } |
600 } | |
601 } | |
602 | |
603 |