Mercurial > MadButterfly
annotate nodejs/svg.js @ 703:3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
author | wycc |
---|---|
date | Fri, 13 Aug 2010 08:16:18 +0800 |
parents | 492da72e6537 |
children | d950487bd9f9 |
rev | line source |
---|---|
624 | 1 var libxml = require('libxmljs'); |
2 var sys=require('sys'); | |
3 var mbfly = require("mbfly"); | |
4 var mb_rt = new mbfly.mb_rt(":0.0", 720,480); | |
646 | 5 var ldr = mbfly.img_ldr_new("."); |
624 | 6 |
7 function MB_loadSVG(mb_rt,root,filename) { | |
8 var doc = libxml.parseXmlFile(filename); | |
9 var nodes = doc.root().childNodes(); | |
10 var coord = mb_rt.coord_new(root); | |
11 var k; | |
12 | |
13 for(k in nodes) { | |
14 var n = nodes[k].name(); | |
15 if (n == "defs") { | |
16 _MB_parseDefs(root,nodes[k]); | |
17 } else if (n == "g") { | |
18 _MB_parseGroup(root,'root_coord',nodes[k]); | |
19 } | |
20 } | |
21 } | |
22 | |
23 function getInteger(n,name) | |
24 { | |
25 if (n == null) return 0; | |
26 var a = n.attr(name); | |
27 if (a==null) return 0; | |
28 return parseInt(a.value()); | |
29 } | |
631 | 30 function parsePointSize(s) |
31 { | |
32 var fs=0; | |
33 var i; | |
624 | 34 |
631 | 35 for(i=0;i<s.length;i++) { |
36 if (s[i]<'0' || s[i] > '9') break; | |
37 fs = fs*10 + (s[i]-'0'); | |
38 } | |
39 return fs; | |
40 | |
41 } | |
42 | |
43 | |
44 function parseColor(c) | |
45 { | |
46 if (c[0] == '#') { | |
47 return parseInt(c.substring(1,3),16)<<16 | parseInt(c.substring(3,5),16)<<8 | parseInt(c.substring(5,7),16); | |
48 } | |
49 } | |
50 function parseTextStyle(style,n) | |
624 | 51 { |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
52 var attr; |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
53 if (n) { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
54 attr = n.attr('style'); |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
55 } else { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
56 attr = null; |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
57 } |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
58 if (attr == null) { |
631 | 59 return; |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
60 } |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
61 var f = attr.value().split(';'); |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
62 |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
63 for(i in f) { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
64 var kv = f[i].split(':'); |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
65 if (kv[0] == 'font-size') { |
631 | 66 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
|
67 } 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
|
68 } 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
|
69 } else if (kv[0] == "fill") { |
631 | 70 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
|
71 } 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
|
72 } 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
|
73 } else if (kv[0] == "stroke") { |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
74 } 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
|
75 } 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
|
76 } 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
|
77 } 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
|
78 } else if (kv[0] == "font-family") { |
631 | 79 style.family = kv[1]; |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
80 } 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
|
81 } 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
|
82 } 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
|
83 } 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
|
84 } 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
|
85 } else if (kv[0] == "line-height") { |
632 | 86 } else { |
625
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
87 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
|
88 } |
9f2080b68f8e
Add the text style parser. This can not handle the recursive tspan yet.
wycc
parents:
624
diff
changeset
|
89 } |
624 | 90 } |
91 | |
631 | 92 function _MB_parseTSpan(coord, n,style) |
624 | 93 { |
94 var x = getInteger(n,'x'); | |
95 var y = getInteger(n,'y'); | |
96 var tcoord = mb_rt.coord_new(coord); | |
97 var nodes = n.childNodes(); | |
98 var k; | |
99 | |
100 sys.puts(n.text()); | |
101 var obj = mb_rt.stext_new(n.text(),x,y); | |
631 | 102 parseTextStyle(style,n); |
103 style.paint = mb_rt.paint_color_new(1,1,1,1); | |
104 style.face=mb_rt.font_face_query(style.family, 2, 100); | |
105 obj.set_style([[20,style.face,style.fs]]); | |
106 style.paint.fill(obj); | |
624 | 107 tcoord.add_shape(obj); |
108 for(k in nodes) { | |
109 var name = nodes[k].name(); | |
110 if (name == "tspan") { | |
111 _MB_parseTSpan(tcoord,nodes[k]); | |
112 } else { | |
113 } | |
114 } | |
115 } | |
116 | |
117 function _MB_parseText(coord,id, n) | |
118 { | |
119 var x = getInteger(n,'x'); | |
120 var y = getInteger(n,'y'); | |
121 var tcoord = mb_rt.coord_new(coord); | |
631 | 122 var style = new Object(); |
123 style.fs = 20; | |
124 style.family = 'courier'; | |
125 parseTextStyle(style,n); | |
624 | 126 var nodes = n.childNodes(); |
127 var k; | |
128 for(k in nodes) { | |
129 var n = nodes[k].name(); | |
130 if (n == "tspan") { | |
631 | 131 _MB_parseTSpan(tcoord,nodes[k],style); |
624 | 132 } else { |
133 } | |
134 } | |
135 | |
136 | |
137 } | |
138 | |
139 | |
140 function parseTransform(coord, s) | |
141 { | |
142 var off = s.indexOf('translate'); | |
143 if (off != -1) { | |
144 var ss = s.substring(off+9); | |
145 for(i=0;i<ss.length;i++) { | |
146 if (ss[i] == '(') break; | |
147 } | |
148 ss = ss.substring(i+1); | |
149 for(i=0;i<ss.length;i++) { | |
150 if (ss[i] == ')') { | |
151 ss = ss.substring(0,i); | |
152 break; | |
153 } | |
154 } | |
155 var f = ss.split(','); | |
156 var x,y; | |
157 x = parseInt(f[0]); | |
158 y = parseInt(f[1]); | |
159 coord[2] = x; | |
160 coord[5] = y; | |
161 } | |
162 off = s.indexOf('matrix'); | |
163 if (off != -1) { | |
164 sys.puts("matrix"); | |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
165 var end = s.indexOf(')'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
166 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
|
167 var fields = m.split(','); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
168 coord[0] = parseFloat(fields[0]); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
169 coord[1] = parseFloat(fields[1]); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
170 coord[2] = parseFloat(fields[4]); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
171 coord[3] = parseFloat(fields[2]); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
172 coord[4] = parseFloat(fields[3]); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
173 coord[5] = parseFloat(fields[5]); |
624 | 174 } |
175 } | |
176 | |
177 function _MB_parseRect(coord, id, n) | |
178 { | |
703
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
179 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
|
180 var y = getInteger(n,'y'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
181 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
|
182 var h = getInteger(n,'height'); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
183 var paint; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
184 |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
185 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
|
186 |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
187 if (style==null) { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
188 paint = mb_rt.paint_color_new(0,0,0,0.1); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
189 } else { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
190 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
|
191 var fill = ''; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
192 var alpha; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
193 for(i in items) { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
194 sys.puts(items[i]); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
195 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
|
196 if (f[0] == 'opacity') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
197 alpha = f[1]; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
198 } 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
|
199 fill = f[1]; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
200 } 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
|
201 } 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
|
202 } 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
|
203 } 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
|
204 } |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
205 } |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
206 sys.puts("fill="+fill); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
207 if (fill[0]=='#') { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
208 var r,g,b; |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
209 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
|
210 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
|
211 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
|
212 sys.puts("r="+r+" g="+g+" b="+b+" a="+alpha); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
213 |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
214 paint = mb_rt.paint_color_new(r,g,b,parseFloat(alpha)); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
215 } else { |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
216 paint = mb_rt.paint_color_new(0,0,0,1); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
217 } |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
218 } |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
219 var rect = mb_rt.rect_new(x,y,w,h,10, 10); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
220 sys.puts("rect x="+x+" y="+y+" w="+w+" h="+h); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
221 paint.fill(rect); |
3457519e3b9c
Add rect and matrix support. The test.svg can be rendered almost correctly now.
wycc
parents:
647
diff
changeset
|
222 coord.add_shape(rect); |
624 | 223 } |
224 | |
225 function _MB_parseGroup(root, group_id, n) | |
226 { | |
227 var k; | |
228 var nodes = n.childNodes(); | |
229 var coord = mb_rt.coord_new(root); | |
230 // Parse the transform and style here | |
231 var trans = n.attr('transform'); | |
232 if (trans!=null) { | |
233 parseTransform(coord, trans.value()); | |
234 } | |
235 | |
236 for(k in nodes) { | |
237 var n = nodes[k].name(); | |
238 var attr = nodes[k].attr('id'); | |
239 var id; | |
240 if (attr) { | |
241 id = attr.value(); | |
242 } | |
243 if (n == "g") { | |
244 _MB_parseGroup(coord, id, nodes[k]); | |
245 } else if (n == "text") { | |
246 _MB_parseText(coord, id, nodes[k]); | |
247 } else if (n == "rect") { | |
248 _MB_parseRect(coord, id, nodes[k]); | |
646 | 249 } else if (n == "image") { |
250 _MB_parseImage(coord, id, nodes[k]); | |
624 | 251 } |
252 } | |
253 | |
254 } | |
255 | |
646 | 256 function _MB_parseImage(coord,id, n) |
257 { | |
258 sys.puts("---> image"); | |
259 var ref = n.attr('href').value(); | |
260 | |
261 if (ref == null) return; | |
262 sys.puts(ref); | |
647 | 263 if (ref.substr(0,7) == "file://") { |
264 ref = ref.substring(7); | |
265 } else if (ref.substr(0,5)=="file:") { | |
266 ref = ref.substring(5); | |
267 } else { | |
646 | 268 return; |
269 } | |
270 sys.puts("Load image "+ref); | |
271 var w; | |
272 var h; | |
273 var x,y; | |
274 | |
275 w = n.attr("width"); | |
276 if (w == null) return; | |
277 w = parseInt(w.value()); | |
278 h = n.attr("height"); | |
279 if (h == null) return; | |
280 h = parseInt(h.value()); | |
281 x = n.attr("x"); | |
282 if (x == null) return; | |
283 x = parseInt(x.value()); | |
284 y = n.attr("y"); | |
285 if (y == null) return; | |
286 y = parseInt(y.value()); | |
287 sys.puts("x="+x+",y="+y+",w="+w+",h="+h); | |
288 var img = mb_rt.image_new(x,y,w,h); | |
289 var img_data = ldr.load(ref); | |
290 sys.puts(img_data); | |
291 var paint = mb_rt.paint_image_new(img_data); | |
292 paint.fill(img); | |
293 coord.add_shape(img); | |
294 } | |
624 | 295 |
296 function _MB_parseDefs(root,n) | |
297 { | |
298 var k; | |
299 var nodes = n.childNodes(); | |
300 | |
301 for(k in nodes) { | |
302 var name = nodes[k].name(); | |
303 if (name == "linearGradient") { | |
304 //_MB_parseLinearGradient(root,nodes[k]); | |
305 } | |
306 } | |
307 } | |
308 | |
309 | |
310 MB_loadSVG(mb_rt,mb_rt.root,"test.svg"); | |
311 mb_rt.redraw_all(); |