comparison nodejs/svg.js @ 759:ae1ae29348d1

Add origin calculation support
author wycc
date Sat, 28 Aug 2010 22:14:38 +0800
parents 199bac90b90a
children 77b561bb7929
comparison
equal deleted inserted replaced
758:d11b0900f03c 759:ae1ae29348d1
17 function loadSVG(mb_rt, root, filename) { 17 function loadSVG(mb_rt, root, filename) {
18 var doc = libxml.parseXmlFile(filename); 18 var doc = libxml.parseXmlFile(filename);
19 var nodes = doc.root().childNodes(); 19 var nodes = doc.root().childNodes();
20 var coord = mb_rt.coord_new(root); 20 var coord = mb_rt.coord_new(root);
21 var k; 21 var k;
22 var accu=[1,0,0,0,1,0];
22 this.mb_rt = mb_rt; 23 this.mb_rt = mb_rt;
23 this.stop_ref={}; 24 this.stop_ref={};
24 this.gradients={}; 25 this.gradients={};
25 26
26 for(k in nodes) { 27 for(k in nodes) {
27 var n = nodes[k].name(); 28 var n = nodes[k].name();
28 if (n == "defs") { 29 if (n == "defs") {
29 this.parseDefs(root,nodes[k]); 30 this.parseDefs(root,nodes[k]);
30 } else if (n == "g") { 31 } else if (n == "g") {
31 this.parseGroup(root,'root_coord',nodes[k]); 32 this.parseGroup(accu,root,'root_coord',nodes[k]);
32 } 33 }
33 } 34 }
34 } 35 }
35 36
36 function make_mbnames(mb_rt, n, obj) { 37 function make_mbnames(mb_rt, n, obj) {
165 paint = this.mb_rt.paint_color_new(0,0,0,1); 166 paint = this.mb_rt.paint_color_new(0,0,0,1);
166 } 167 }
167 return paint; 168 return paint;
168 } 169 }
169 170
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
170 loadSVG.prototype.parsePath=function(coord,id, n) 227 loadSVG.prototype.parsePath=function(coord,id, n)
171 { 228 {
172 var d = n.attr('d').value(); 229 var d = n.attr('d').value();
173 var style = n.attr('style'); 230 var style = n.attr('style');
174 var path = this.mb_rt.path_new(d); 231 var path = this.mb_rt.path_new(d);
177 var stroke_alpha = 1; 234 var stroke_alpha = 1;
178 var fill_color; 235 var fill_color;
179 var stroke_color; 236 var stroke_color;
180 var black_paint; 237 var black_paint;
181 238
239 guessPathBoundingBox(coord,d);
182 if(style != null) { 240 if(style != null) {
183 var items = style.value().split(';'); 241 var items = style.value().split(';');
184 var alpha; 242 var alpha;
185 243
186 for(i in items) { 244 for(i in items) {
207 265
208 if(fill_color) { 266 if(fill_color) {
209 if(fill_color != "none") { 267 if(fill_color != "none") {
210 paint = this._prepare_paint_color(fill_color, fill_alpha); 268 paint = this._prepare_paint_color(fill_color, fill_alpha);
211 paint.fill(path); 269 paint.fill(path);
270 sys.puts("paint path with "+fill_color+" "+fill_alpha);
212 } 271 }
213 } else { 272 } else {
214 black_paint.fill(path); 273 black_paint.fill(path);
215 } 274 }
216 if(stroke_color) { 275 if(stroke_color) {
217 if(stroke_color != "none") { 276 if(stroke_color != "none") {
218 paint = this._prepare_paint_color(stroke_color, stroke_alpha); 277 paint = this._prepare_paint_color(stroke_color, stroke_alpha);
219 paint.stroke(path); 278 paint.stroke(path);
279 sys.puts("stroke path");
220 } 280 }
221 } else { 281 } else {
222 black_paint.stroke(path); 282 black_paint.stroke(path);
223 } 283 }
224 coord.add_shape(path); 284 coord.add_shape(path);
230 { 290 {
231 var x = getInteger(n,'x'); 291 var x = getInteger(n,'x');
232 var y = getInteger(n,'y'); 292 var y = getInteger(n,'y');
233 var tcoord = this.mb_rt.coord_new(coord); 293 var tcoord = this.mb_rt.coord_new(coord);
234 var style = new Object(); 294 var style = new Object();
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;
235 style.fs = 20; 302 style.fs = 20;
236 style.family = 'courier'; 303 style.family = 'courier';
237 parseTextStyle(style,n); 304 parseTextStyle(style,n);
238 var nodes = n.childNodes(); 305 var nodes = n.childNodes();
239 var k; 306 var k;
246 } 313 }
247 314
248 make_mbnames(this.mb_rt, n, tcoord); 315 make_mbnames(this.mb_rt, n, tcoord);
249 } 316 }
250 317
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
251 function parseTransform(coord, s) 335 function parseTransform(coord, s)
252 { 336 {
253 var off = s.indexOf('translate'); 337 var off = s.indexOf('translate');
254 if (off != -1) { 338 if (off != -1) {
255 var ss = s.substring(off+9); 339 var ss = s.substring(off+9);
265 } 349 }
266 var f = ss.split(','); 350 var f = ss.split(',');
267 var x,y; 351 var x,y;
268 x = parseFloat(f[0]); 352 x = parseFloat(f[0]);
269 y = parseFloat(f[1]); 353 y = parseFloat(f[1]);
270 coord[0] = 1; 354 coord[2] += x;
271 coord[1] = 0; 355 coord[5] += y;
272 coord[2] = x;
273 coord[3] = 0;
274 coord[4] = 1;
275 coord[5] = y;
276 } 356 }
277 off = s.indexOf('matrix'); 357 off = s.indexOf('matrix');
278 if (off != -1) { 358 if (off != -1) {
279 var end = s.indexOf(')'); 359 var end = s.indexOf(')');
280 var m = s.substring(7,end); 360 var m = s.substring(7,end);
281 var fields = m.split(','); 361 var fields = m.split(',');
282 coord[0] = parseFloat(fields[0]); 362 var newm=[];
283 coord[1] = parseFloat(fields[2]); 363 newm[0] = parseFloat(fields[0]);
284 coord[2] = parseFloat(fields[4]); 364 newm[1] = parseFloat(fields[2]);
285 coord[3] = parseFloat(fields[1]); 365 newm[2] = parseFloat(fields[4]);
286 coord[4] = parseFloat(fields[3]); 366 newm[3] = parseFloat(fields[1]);
287 coord[5] = parseFloat(fields[5]); 367 newm[4] = parseFloat(fields[3]);
288 } 368 newm[5] = parseFloat(fields[5]);
289 } 369 multiply(coord,newm);
290 370 }
291 loadSVG.prototype.parseRect=function(coord, id, n) 371 }
292 { 372
373 loadSVG.prototype.parseRect=function(accu_matrix,coord, id, n)
374 {
375 sys.puts("rect");
293 var x = getInteger(n,'x'); 376 var x = getInteger(n,'x');
294 var y = getInteger(n,'y'); 377 var y = getInteger(n,'y');
378 var rx,ry;
295 var w = getInteger(n,'width'); 379 var w = getInteger(n,'width');
296 var h = getInteger(n,'height'); 380 var h = getInteger(n,'height');
381 var trans = n.attr('transform');
297 var paint; 382 var paint;
298 383
299 var style = n.attr('style'); 384 var style = n.attr('style');
385
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];
300 400
301 if (style==null) { 401 if (style==null) {
302 paint = this.mb_rt.paint_color_new(0,0,0,0.1); 402 paint = this.mb_rt.paint_color_new(0,0,0,0.1);
303 } else { 403 } else {
304 var items = style.value().split(';'); 404 var items = style.value().split(';');
335 var rect = this.mb_rt.rect_new(x,y,w,h,10, 10); 435 var rect = this.mb_rt.rect_new(x,y,w,h,10, 10);
336 paint.fill(rect); 436 paint.fill(rect);
337 coord.add_shape(rect); 437 coord.add_shape(rect);
338 } 438 }
339 439
340 loadSVG.prototype.parseGroup=function(root, group_id, n) 440 loadSVG.prototype.parseGroup=function(accu_matrix,root, group_id, n)
341 { 441 {
342 var k; 442 var k;
343 var nodes = n.childNodes(); 443 var nodes = n.childNodes();
344 var coord = this.mb_rt.coord_new(root); 444 var coord = this.mb_rt.coord_new(root);
345 // Parse the transform and style here 445 // Parse the transform and style here
346 var trans = n.attr('transform'); 446 var trans = n.attr('transform');
447 var accu=[1,0,0,0,1,0];
448 coord.center= new Object();
449 coord.center.x = 10000;
450 coord.center.y = 10000;
347 if (trans!=null) { 451 if (trans!=null) {
348 parseTransform(coord, trans.value()); 452 parseTransform(coord, trans.value());
349 } 453 }
454 accu[2] = accu_matrix[2]+coord[2];
455 accu[5] = accu_matrix[5]+coord[5];
456
350 457
351 for(k in nodes) { 458 for(k in nodes) {
352 var c = nodes[k].name(); 459 var c = nodes[k].name();
353 var attr = nodes[k].attr('id'); 460 var attr = nodes[k].attr('id');
354 var id; 461 var id;
355 if (attr) { 462 if (attr) {
356 id = attr.value(); 463 id = attr.value();
357 } 464 }
358 if (c == "g") { 465 if (c == "g") {
359 this.parseGroup(coord, id, nodes[k]); 466 this.parseGroup(accu,coord, id, nodes[k]);
360 } else if (c == "path") { 467 } else if (c == "path") {
361 this.parsePath(coord, id, nodes[k]); 468 this.parsePath(coord, id, nodes[k]);
362 } else if (c == "text") { 469 } else if (c == "text") {
363 this.parseText(coord, id, nodes[k]); 470 this.parseText(coord, id, nodes[k]);
364 } else if (c == "rect") { 471 } else if (c == "rect") {
365 this.parseRect(coord, id, nodes[k]); 472 this.parseRect(accu_matrix,coord, id, nodes[k]);
366 } else if (c == "image") { 473 } else if (c == "image") {
367 this.parseImage(coord, id, nodes[k]); 474 this.parseImage(coord, id, nodes[k]);
368 } 475 }
369 } 476 }
370
371 make_mbnames(this.mb_rt, n, coord); 477 make_mbnames(this.mb_rt, n, coord);
372 } 478 }
373 479
374 loadSVG.prototype.parseImage=function(coord,id, n) 480 loadSVG.prototype.parseImage=function(coord,id, n)
375 { 481 {
381 } else if (ref.substr(0,5)=="file:") { 487 } else if (ref.substr(0,5)=="file:") {
382 ref = ref.substring(5); 488 ref = ref.substring(5);
383 } else { 489 } else {
384 return; 490 return;
385 } 491 }
386 sys.puts("Load image "+ref);
387 var w; 492 var w;
388 var h; 493 var h;
389 var x,y; 494 var x,y;
390 495
391 w = n.attr("width"); 496 w = n.attr("width");
392 if (w == null) return; 497 if (w == null) return;
393 w = parseInt(w.value()); 498 w = parseFloat(w.value());
394 h = n.attr("height"); 499 h = n.attr("height");
395 if (h == null) return; 500 if (h == null) return;
396 h = parseInt(h.value()); 501 h = parseFloat(h.value());
397 x = n.attr("x"); 502 x = n.attr("x");
398 if (x == null) return; 503 if (x == null) return;
399 x = parseInt(x.value()); 504 x = parseFloat(x.value());
400 y = n.attr("y"); 505 y = n.attr("y");
401 if (y == null) return; 506 if (y == null) return;
402 y = parseInt(y.value()); 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;
403 var img = this.mb_rt.image_new(x,y,w,h); 512 var img = this.mb_rt.image_new(x,y,w,h);
404 var img_data = ldr.load(ref); 513 var img_data = ldr.load(ref);
405 var paint = this.mb_rt.paint_image_new(img_data); 514 var paint = this.mb_rt.paint_image_new(img_data);
406 paint.fill(img); 515 paint.fill(img);
407 coord.add_shape(img); 516 coord.add_shape(img);