Mercurial > MadButterfly
comparison nodejs/svg.js @ 776:77b561bb7929
Implement new algorithm to calculate the origin of the SVG elemnts so that we can implement object resize without changing the position of the object.
However, the image does not work here since it does not use the transformation of the group.
author | wycc |
---|---|
date | Mon, 30 Aug 2010 08:56:44 +0800 |
parents | ae1ae29348d1 |
children | a47431293043 |
comparison
equal
deleted
inserted
replaced
775:caa2fdb5f220 | 776:77b561bb7929 |
---|---|
1 // vim: ts=4 | |
1 var libxml = require('libxmljs'); | 2 var libxml = require('libxmljs'); |
2 var sys=require('sys'); | 3 var sys=require('sys'); |
3 var mbfly = require("mbfly"); | 4 var mbfly = require("mbfly"); |
4 var ldr = mbfly.img_ldr_new("."); | 5 var ldr = mbfly.img_ldr_new("."); |
5 | 6 |
21 var k; | 22 var k; |
22 var accu=[1,0,0,0,1,0]; | 23 var accu=[1,0,0,0,1,0]; |
23 this.mb_rt = mb_rt; | 24 this.mb_rt = mb_rt; |
24 this.stop_ref={}; | 25 this.stop_ref={}; |
25 this.gradients={}; | 26 this.gradients={}; |
27 root.center=new Object(); | |
28 root.center.x = 10000; | |
29 root.center.y = 10000; | |
26 | 30 |
27 for(k in nodes) { | 31 for(k in nodes) { |
28 var n = nodes[k].name(); | 32 var n = nodes[k].name(); |
29 if (n == "defs") { | 33 if (n == "defs") { |
30 this.parseDefs(root,nodes[k]); | 34 this.parseDefs(root,nodes[k]); |
168 return paint; | 172 return paint; |
169 } | 173 } |
170 | 174 |
171 function guessPathBoundingBox(coord,d) | 175 function guessPathBoundingBox(coord,d) |
172 { | 176 { |
177 return; | |
173 var items = d.split(' '); | 178 var items = d.split(' '); |
174 var len = items.length; | 179 var len = items.length; |
175 var pair; | 180 var pair; |
176 var i; | 181 var i; |
177 var minx,miny; | 182 var minx,miny; |
211 x = parseFloat(items[i+1]); | 216 x = parseFloat(items[i+1]); |
212 break; | 217 break; |
213 case 'v': | 218 case 'v': |
214 y = parseFloat(items[i+1]); | 219 y = parseFloat(items[i+1]); |
215 break; | 220 break; |
221 default: | |
222 continue; | |
216 } | 223 } |
217 if (x < minx) minx = x; | 224 if (x < minx) minx = x; |
218 if (y < miny) miny = y; | 225 if (y < miny) miny = y; |
219 } | 226 } |
220 if (coord.center.x > minx) | 227 if (coord.center.x > minx) |
265 | 272 |
266 if(fill_color) { | 273 if(fill_color) { |
267 if(fill_color != "none") { | 274 if(fill_color != "none") { |
268 paint = this._prepare_paint_color(fill_color, fill_alpha); | 275 paint = this._prepare_paint_color(fill_color, fill_alpha); |
269 paint.fill(path); | 276 paint.fill(path); |
270 sys.puts("paint path with "+fill_color+" "+fill_alpha); | |
271 } | 277 } |
272 } else { | 278 } else { |
273 black_paint.fill(path); | 279 black_paint.fill(path); |
274 } | 280 } |
275 if(stroke_color) { | 281 if(stroke_color) { |
276 if(stroke_color != "none") { | 282 if(stroke_color != "none") { |
277 paint = this._prepare_paint_color(stroke_color, stroke_alpha); | 283 paint = this._prepare_paint_color(stroke_color, stroke_alpha); |
278 paint.stroke(path); | 284 paint.stroke(path); |
279 sys.puts("stroke path"); | |
280 } | 285 } |
281 } else { | 286 } else { |
282 black_paint.stroke(path); | 287 black_paint.stroke(path); |
283 } | 288 } |
284 coord.add_shape(path); | 289 coord.add_shape(path); |
285 | 290 |
286 make_mbnames(this.mb_rt, n, path); | 291 make_mbnames(this.mb_rt, n, path); |
287 } | 292 } |
288 | 293 |
289 loadSVG.prototype.parseText=function(coord,id, n) | 294 loadSVG.prototype.parseText=function(accu,coord,id, n) |
290 { | 295 { |
291 var x = getInteger(n,'x'); | 296 var x = getInteger(n,'x'); |
292 var y = getInteger(n,'y'); | 297 var y = getInteger(n,'y'); |
293 var tcoord = this.mb_rt.coord_new(coord); | 298 var tcoord = this.mb_rt.coord_new(coord); |
294 var style = new Object(); | 299 var style = new Object(); |
295 | 300 |
296 if (n.attr('x')) | 301 if (n.attr('x')) { |
297 if (coord.center.x > x) | 302 var nx = coord[0]*x+coord[1]*y+coord[2]; |
298 coord.center.x = x; | 303 if (coord.center.x > nx) |
299 if (n.attr('y')) | 304 coord.center.x = nx; |
300 if (coord.center.y > y) | 305 } |
301 coord.center.y = y; | 306 if (n.attr('y')) { |
307 var ny = coord[3]*x+coord[4]*y+coord[5]; | |
308 if (coord.center.y > ny) | |
309 coord.center.y = ny; | |
310 } | |
302 style.fs = 20; | 311 style.fs = 20; |
303 style.family = 'courier'; | 312 style.family = 'courier'; |
304 parseTextStyle(style,n); | 313 parseTextStyle(style,n); |
305 var nodes = n.childNodes(); | 314 var nodes = n.childNodes(); |
306 var k; | 315 var k; |
370 } | 379 } |
371 } | 380 } |
372 | 381 |
373 loadSVG.prototype.parseRect=function(accu_matrix,coord, id, n) | 382 loadSVG.prototype.parseRect=function(accu_matrix,coord, id, n) |
374 { | 383 { |
375 sys.puts("rect"); | |
376 var x = getInteger(n,'x'); | 384 var x = getInteger(n,'x'); |
377 var y = getInteger(n,'y'); | 385 var y = getInteger(n,'y'); |
378 var rx,ry; | 386 var rx,ry; |
379 var w = getInteger(n,'width'); | 387 var w = getInteger(n,'width'); |
380 var h = getInteger(n,'height'); | 388 var h = getInteger(n,'height'); |
381 var trans = n.attr('transform'); | 389 var trans = n.attr('transform'); |
382 var paint; | 390 var paint; |
391 var tcoord = this.mb_rt.coord_new(coord); | |
383 | 392 |
384 var style = n.attr('style'); | 393 var style = n.attr('style'); |
385 | 394 |
386 if (trans) { | 395 if (trans) { |
387 parseTransform(coord,trans.value()); | 396 parseTransform(tcoord,trans.value()); |
388 var m = [1,0,0,0,1,0]; | 397 //var m = [1,0,0,0,1,0]; |
389 parseTransform(m,trans.value()); | 398 //multiply(m,tcoord); |
390 rx = x+m[2]; | 399 rx = tcoord[0]*x+tcoord[1]*y+tcoord[2]; |
391 ry = y+m[5]; | 400 ry = tcoord[3]*x+tcoord[4]*y+tcoord[5]; |
392 } | 401 } |
393 | 402 |
394 if (coord.center.x > rx) | 403 if (coord.center.x > rx) |
395 coord.center.x = rx; | 404 coord.center.x = rx; |
396 if (coord.center.y > ry) | 405 if (coord.center.y > ry) |
397 coord.center.y = ry; | 406 coord.center.y = ry; |
398 coord.center.x += accu_matrix[2]; | |
399 coord.center.y += accu_matrix[5]; | |
400 | 407 |
401 if (style==null) { | 408 if (style==null) { |
402 paint = this.mb_rt.paint_color_new(0,0,0,0.1); | 409 paint = this.mb_rt.paint_color_new(0,0,0,0.1); |
403 } else { | 410 } else { |
404 var items = style.value().split(';'); | 411 var items = style.value().split(';'); |
405 var fill = ''; | 412 var fill = ''; |
406 var alpha = 1; | 413 var alpha = 1; |
414 display = 'on'; | |
407 for(i in items) { | 415 for(i in items) { |
408 var f = items[i].split(':'); | 416 var f = items[i].split(':'); |
409 if (f[0] == 'opacity') { | 417 if (f[0] == 'opacity') { |
410 alpha = f[1]; | 418 alpha = f[1]; |
411 } else if (f[0] == 'fill') { | 419 } else if (f[0] == 'fill') { |
412 fill = f[1]; | 420 fill = f[1]; |
413 } else if (f[0] == 'fill-opacity') { | 421 } else if (f[0] == 'fill-opacity') { |
414 } else if (f[0] == 'stroke') { | 422 } else if (f[0] == 'stroke') { |
415 } else if (f[0] == 'stroken-width') { | 423 } else if (f[0] == 'stroken-width') { |
416 } else if (f[0] == 'stroke-opacity') { | 424 } else if (f[0] == 'stroke-opacity') { |
425 } else if (f[0] == 'display') { | |
426 display = f[1]; | |
417 } | 427 } |
418 } | 428 } |
429 if (display == 'none') { | |
430 return; | |
431 } | |
419 if (fill[0]=='#') { | 432 if (fill[0]=='#') { |
420 var r,g,b; | 433 var r,g,b; |
421 r = parseInt(fill.substring(1,3),16)/256; | 434 r = parseInt(fill.substring(1,3),16)/256; |
422 g = parseInt(fill.substring(3,5),16)/256; | 435 g = parseInt(fill.substring(3,5),16)/256; |
423 b = parseInt(fill.substring(5,7),16)/256; | 436 b = parseInt(fill.substring(5,7),16)/256; |
432 paint = this.mb_rt.paint_color_new(0,0,0,1); | 445 paint = this.mb_rt.paint_color_new(0,0,0,1); |
433 } | 446 } |
434 } | 447 } |
435 var rect = this.mb_rt.rect_new(x,y,w,h,10, 10); | 448 var rect = this.mb_rt.rect_new(x,y,w,h,10, 10); |
436 paint.fill(rect); | 449 paint.fill(rect); |
437 coord.add_shape(rect); | 450 tcoord.add_shape(rect); |
438 } | 451 } |
439 | 452 // When we parse a group, we need to calculate the origin of the group so that we can resize the group without changing its origin point. |
453 // This must be done recursively. For text/rect/image, we can get its origin point directly by using the (x,y) and apply their transformation | |
454 // matrix. For group, we need to send the acculumated matrix so that each group can get their origin correctly. | |
455 // | |
456 // Each element must be responsible to calculate its absolute origin point and update the origin of its parent. | |
440 loadSVG.prototype.parseGroup=function(accu_matrix,root, group_id, n) | 457 loadSVG.prototype.parseGroup=function(accu_matrix,root, group_id, n) |
441 { | 458 { |
442 var k; | 459 var k; |
443 var nodes = n.childNodes(); | 460 var nodes = n.childNodes(); |
444 var coord = this.mb_rt.coord_new(root); | 461 var coord = this.mb_rt.coord_new(root); |
449 coord.center.x = 10000; | 466 coord.center.x = 10000; |
450 coord.center.y = 10000; | 467 coord.center.y = 10000; |
451 if (trans!=null) { | 468 if (trans!=null) { |
452 parseTransform(coord, trans.value()); | 469 parseTransform(coord, trans.value()); |
453 } | 470 } |
454 accu[2] = accu_matrix[2]+coord[2]; | 471 multiply(accu,accu_matrix); |
455 accu[5] = accu_matrix[5]+coord[5]; | 472 multiply(accu,coord); |
456 | |
457 | 473 |
458 for(k in nodes) { | 474 for(k in nodes) { |
459 var c = nodes[k].name(); | 475 var c = nodes[k].name(); |
460 var attr = nodes[k].attr('id'); | 476 var attr = nodes[k].attr('id'); |
461 var id; | 477 var id; |
463 id = attr.value(); | 479 id = attr.value(); |
464 } | 480 } |
465 if (c == "g") { | 481 if (c == "g") { |
466 this.parseGroup(accu,coord, id, nodes[k]); | 482 this.parseGroup(accu,coord, id, nodes[k]); |
467 } else if (c == "path") { | 483 } else if (c == "path") { |
468 this.parsePath(coord, id, nodes[k]); | 484 this.parsePath(accu,coord, id, nodes[k]); |
469 } else if (c == "text") { | 485 } else if (c == "text") { |
470 this.parseText(coord, id, nodes[k]); | 486 this.parseText(accu,coord, id, nodes[k]); |
471 } else if (c == "rect") { | 487 } else if (c == "rect") { |
472 this.parseRect(accu_matrix,coord, id, nodes[k]); | 488 this.parseRect(accu_matrix,coord, id, nodes[k]); |
473 } else if (c == "image") { | 489 } else if (c == "image") { |
474 this.parseImage(coord, id, nodes[k]); | 490 this.parseImage(accu_matrix,coord, id, nodes[k]); |
475 } | 491 } |
476 } | 492 } |
493 if (root.center.x > coord.center.x) | |
494 root.center.x = coord.center.x; | |
495 if (root.center.y > coord.center.y) | |
496 root.center.y = coord.center.y; | |
477 make_mbnames(this.mb_rt, n, coord); | 497 make_mbnames(this.mb_rt, n, coord); |
478 } | 498 } |
479 | 499 |
480 loadSVG.prototype.parseImage=function(coord,id, n) | 500 loadSVG.prototype.parseImage=function(accu,coord,id, n) |
481 { | 501 { |
482 var ref = n.attr('href').value(); | 502 var ref = n.attr('href').value(); |
503 var tcoord = this.mb_rt.coord_new(coord); | |
504 var trans = n.attr('transform'); | |
483 | 505 |
484 if (ref == null) return; | 506 if (ref == null) return; |
485 if (ref.substr(0,7) == "file://") { | 507 if (ref.substr(0,7) == "file://") { |
486 ref = ref.substring(7); | 508 ref = ref.substring(7); |
487 } else if (ref.substr(0,5)=="file:") { | 509 } else if (ref.substr(0,5)=="file:") { |
489 } else { | 511 } else { |
490 return; | 512 return; |
491 } | 513 } |
492 var w; | 514 var w; |
493 var h; | 515 var h; |
494 var x,y; | 516 var x,y,nx,ny; |
517 coord.center= new Object(); | |
518 coord.center.x = 10000; | |
519 coord.center.y = 10000; | |
520 if (trans!=null) { | |
521 parseTransform(coord, trans.value()); | |
522 } | |
495 | 523 |
496 w = n.attr("width"); | 524 w = n.attr("width"); |
497 if (w == null) return; | 525 if (w == null) return; |
498 w = parseFloat(w.value()); | 526 w = parseFloat(w.value()); |
499 h = n.attr("height"); | 527 h = n.attr("height"); |
503 if (x == null) return; | 531 if (x == null) return; |
504 x = parseFloat(x.value()); | 532 x = parseFloat(x.value()); |
505 y = n.attr("y"); | 533 y = n.attr("y"); |
506 if (y == null) return; | 534 if (y == null) return; |
507 y = parseFloat(y.value()); | 535 y = parseFloat(y.value()); |
508 if (coord.center.x > x) | 536 nx = tcoord[0]*x+tcoord[1]*y+tcoord[2]; |
509 coord.center.x = x; | 537 ny = tcoord[3]*x+tcoord[4]*y+tcoord[5]; |
510 if (coord.center.y > y) | 538 if (coord.center.x > nx) |
511 coord.center.y = y; | 539 coord.center.x = nx; |
540 if (coord.center.y > ny) | |
541 coord.center.y = ny; | |
512 var img = this.mb_rt.image_new(x,y,w,h); | 542 var img = this.mb_rt.image_new(x,y,w,h); |
513 var img_data = ldr.load(ref); | 543 var img_data = ldr.load(ref); |
514 var paint = this.mb_rt.paint_image_new(img_data); | 544 var paint = this.mb_rt.paint_image_new(img_data); |
515 paint.fill(img); | 545 paint.fill(img); |
516 coord.add_shape(img); | 546 tcoord.add_shape(img); |
517 make_mbnames(this.mb_rt, n, img); | 547 make_mbnames(this.mb_rt, n, img); |
518 } | 548 } |
519 | 549 |
520 loadSVG.prototype._MB_parseLinearGradient=function(root,n) | 550 loadSVG.prototype._MB_parseLinearGradient=function(root,n) |
521 { | 551 { |