diff 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
line wrap: on
line diff
--- a/nodejs/svg.js	Sun Aug 29 23:58:43 2010 +0800
+++ b/nodejs/svg.js	Mon Aug 30 08:56:44 2010 +0800
@@ -1,3 +1,4 @@
+// vim: ts=4
 var libxml = require('libxmljs');
 var sys=require('sys');
 var mbfly = require("mbfly");
@@ -23,6 +24,9 @@
 	this.mb_rt = mb_rt;
 	this.stop_ref={};
 	this.gradients={};
+	root.center=new Object();
+	root.center.x = 10000;
+	root.center.y = 10000;
 
     for(k in nodes) {
 	    var n = nodes[k].name();
@@ -170,6 +174,7 @@
 
 function guessPathBoundingBox(coord,d)
 {
+	return;
     var items = d.split(' ');
 	var len = items.length;
 	var pair;
@@ -213,6 +218,8 @@
 			case 'v':
 				y = parseFloat(items[i+1]);
 				break;
+			default:
+				continue;
 		}
 		if (x < minx) minx = x;
 		if (y < miny) miny = y;
@@ -267,7 +274,6 @@
 	if(fill_color != "none") {
 	    paint = this._prepare_paint_color(fill_color, fill_alpha);
 	    paint.fill(path);
-	    sys.puts("paint path with "+fill_color+" "+fill_alpha);
 	}
     } else {
 	black_paint.fill(path);
@@ -276,7 +282,6 @@
 	if(stroke_color != "none") {
 	    paint = this._prepare_paint_color(stroke_color, stroke_alpha);
 	    paint.stroke(path);
-	    sys.puts("stroke path");
 	}
     } else {
 	black_paint.stroke(path);
@@ -286,19 +291,23 @@
     make_mbnames(this.mb_rt, n, path);
 }
 
-loadSVG.prototype.parseText=function(coord,id, n)
+loadSVG.prototype.parseText=function(accu,coord,id, n)
 {
     var x = getInteger(n,'x');
     var y = getInteger(n,'y');
 	var tcoord = this.mb_rt.coord_new(coord);
     var style = new Object();
 
-    if (n.attr('x'))
-  	    if (coord.center.x > x)
-		    coord.center.x = x;
-	if (n.attr('y'))
-	    if (coord.center.y > y)
-		    coord.center.y = y;
+    if (n.attr('x')) {
+		var nx = coord[0]*x+coord[1]*y+coord[2];
+  	    if (coord.center.x > nx)
+		    coord.center.x = nx;
+	}
+	if (n.attr('y')) {
+		var ny = coord[3]*x+coord[4]*y+coord[5];
+	    if (coord.center.y > ny)
+		    coord.center.y = ny;
+	}
 	style.fs = 20;
 	style.family = 'courier';
 	parseTextStyle(style,n);
@@ -372,7 +381,6 @@
 
 loadSVG.prototype.parseRect=function(accu_matrix,coord, id, n) 
 {
-    sys.puts("rect");
     var x = getInteger(n,'x');
     var y = getInteger(n,'y');
 	var rx,ry;
@@ -380,23 +388,22 @@
     var h = getInteger(n,'height');
 	var trans = n.attr('transform');
 	var paint;
+    var tcoord = this.mb_rt.coord_new(coord);
 	
 	var style = n.attr('style');
 
 	if (trans) {
-		parseTransform(coord,trans.value());
-		var m = [1,0,0,0,1,0];
-		parseTransform(m,trans.value());
-		rx = x+m[2];
-		ry = y+m[5];
+		parseTransform(tcoord,trans.value());
+		//var m = [1,0,0,0,1,0];
+		//multiply(m,tcoord);
+		rx = tcoord[0]*x+tcoord[1]*y+tcoord[2];
+		ry = tcoord[3]*x+tcoord[4]*y+tcoord[5];
 	}
 
 	if (coord.center.x > rx)
 		coord.center.x = rx;
 	if (coord.center.y > ry)
 		coord.center.y = ry;
-	coord.center.x += accu_matrix[2];
-	coord.center.y += accu_matrix[5];
 
 	if (style==null) {
 		paint = this.mb_rt.paint_color_new(0,0,0,0.1);
@@ -404,6 +411,7 @@
 	    var items = style.value().split(';');
 		var fill = '';
 		var alpha = 1;
+		display = 'on';
 		for(i in items) {
 			var f = items[i].split(':');
 			if (f[0] == 'opacity') {
@@ -414,8 +422,13 @@
 			} else if (f[0] == 'stroke') {
 			} else if (f[0] == 'stroken-width') {
 			} else if (f[0] == 'stroke-opacity') {
+			} else if (f[0] == 'display') {
+				display = f[1];
 			}
 		}
+	    if (display == 'none') {
+		    return;
+	    }
 		if (fill[0]=='#') {
 		    var r,g,b;
 			r = parseInt(fill.substring(1,3),16)/256;
@@ -434,9 +447,13 @@
 	}
 	var rect = this.mb_rt.rect_new(x,y,w,h,10, 10);
 	paint.fill(rect);
-	coord.add_shape(rect);
+	tcoord.add_shape(rect);
 }
-
+// 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.
+// 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
+// matrix. For group, we need to send the acculumated matrix so that each group can get their origin correctly.
+//
+// Each element must be responsible to calculate its absolute origin point and update the origin of its parent.
 loadSVG.prototype.parseGroup=function(accu_matrix,root, group_id, n)
 {
     var k;
@@ -451,9 +468,8 @@
 	if (trans!=null) {
 	    parseTransform(coord, trans.value());
 	} 
-	accu[2] = accu_matrix[2]+coord[2];
-	accu[5] = accu_matrix[5]+coord[5];
-
+	multiply(accu,accu_matrix);
+	multiply(accu,coord);
 
 	for(k in nodes) {
 	    var c = nodes[k].name();
@@ -465,21 +481,27 @@
 		if (c == "g") {
 		    this.parseGroup(accu,coord, id, nodes[k]);
 		} else if (c == "path") {
-		    this.parsePath(coord, id, nodes[k]);
+		    this.parsePath(accu,coord, id, nodes[k]);
 		} else if (c == "text") {
-		    this.parseText(coord, id, nodes[k]);
+		    this.parseText(accu,coord, id, nodes[k]);
 		} else if (c == "rect") {
 		    this.parseRect(accu_matrix,coord, id, nodes[k]);
 		} else if (c == "image") {
-			this.parseImage(coord, id, nodes[k]);
+			this.parseImage(accu_matrix,coord, id, nodes[k]);
 		}
 	}
+	if (root.center.x > coord.center.x)
+	    root.center.x = coord.center.x;
+	if (root.center.y > coord.center.y)
+	    root.center.y = coord.center.y;
     make_mbnames(this.mb_rt, n, coord);
 }
 
-loadSVG.prototype.parseImage=function(coord,id, n)
+loadSVG.prototype.parseImage=function(accu,coord,id, n)
 {
 	var ref = n.attr('href').value();
+    var tcoord = this.mb_rt.coord_new(coord);
+	var trans = n.attr('transform');
 
 	if (ref == null) return;
 	if (ref.substr(0,7) == "file://") {
@@ -491,7 +513,13 @@
 	}
 	var w;
 	var h;
-	var x,y;
+	var x,y,nx,ny;
+    coord.center= new Object();
+	coord.center.x = 10000;
+	coord.center.y = 10000;
+	if (trans!=null) {
+	    parseTransform(coord, trans.value());
+	} 
 
 	w = n.attr("width");
 	if (w == null) return;
@@ -505,15 +533,17 @@
 	y = n.attr("y");
 	if (y == null) return;
 	y = parseFloat(y.value());
-	if (coord.center.x > x)
-		coord.center.x = x;
-	if (coord.center.y > y)
-		coord.center.y = y;
+	nx = tcoord[0]*x+tcoord[1]*y+tcoord[2];
+	ny = tcoord[3]*x+tcoord[4]*y+tcoord[5];
+	if (coord.center.x > nx) 
+		coord.center.x = nx;
+	if (coord.center.y > ny)
+		coord.center.y = ny;
 	var img = this.mb_rt.image_new(x,y,w,h);
 	var img_data = ldr.load(ref);
 	var paint = this.mb_rt.paint_image_new(img_data);
 	paint.fill(img);
-	coord.add_shape(img);
+	tcoord.add_shape(img);
     make_mbnames(this.mb_rt, n, img);
 }