# HG changeset patch # User wycc # Date 1300726996 -28800 # Node ID 9ce82873d406a907a218d9d7c5481fd0802f2a50 # Parent 8ecee58c85c68a30bb215428795ae9d1408060ac CHange the SVG parser for the scribbo animation. diff -r 8ecee58c85c6 -r 9ce82873d406 nodejs/svg.js --- a/nodejs/svg.js Sun Mar 13 08:10:57 2011 +0800 +++ b/nodejs/svg.js Tue Mar 22 01:03:16 2011 +0800 @@ -104,7 +104,6 @@ if(mbname) { name = mbname.value(); mb_rt.mbnames[name] = obj; - return; } mbname = n.attr("label"); if(mbname&&(mbname.value()!="")) { @@ -113,7 +112,7 @@ } try { var gname = n.attr('id').value(); - sys.puts(gname); + sys.puts("defone object "+ gname); mb_rt.mbnames[gname] = obj; } catch(e) { } @@ -790,6 +789,9 @@ var style = n.attr('style'); var path = this.mb_rt.path_new(d); var pcoord = this.mb_rt.coord_new(coord); + pcoord.node = n; + n.coord = pcoord; + this._check_duplicate_src(n,pcoord); guessPathBoundingBox(pcoord,d); pcoord.add_shape(path); @@ -806,6 +808,10 @@ var tcoord = this.mb_rt.coord_new(coord); var style; + tcoord.node = n; + n.coord = tcoord; + this._check_duplicate_src(n,tcoord); + if (n.attr('x')) { var nx = coord[0]*x+coord[1]*y+coord[2]; if (coord.center.x > nx) @@ -884,6 +890,53 @@ newm[5] = parseFloat(fields[5]); multiply(coord,newm); } + if (coord[0]*coord[4] == coord[1]*coord[3]) { + sys.puts("Singular affine matrix\n"); + coord.sx = 1; + coord.sy = 1; + coord.r = 0; + coord.tx = 0; + coord.ty = 0; + return; + } + A = coord[0]; + B = coord[3]; + C = coord[1]; + D = coord[4]; + E = coord[2]; + F = coord[5]; + sx = Math.sqrt(A*A+B*B); + A = A / sx; + B = B / sx; + shear = A*C+B*D; + C = C - A*shear; + D = D - B*shear; + sy = Math.sqrt(C*C+D*D); + C = C / sy; + D = D / sy; + r = A*D - B*C; + if (r == -1) { + shear = - shear; + sy = -sy; + } + R = Math.atan2(-B,A); + coord.sx = sx; + coord.sy = sy; + coord.r = R; + coord.tx = E; + coord.ty = F; + sys.puts("transform="+s); + sys.puts("coord[0]="+coord[0]); + sys.puts("coord[1]="+coord[1]); + sys.puts("coord[2]="+coord[2]); + sys.puts("coord[3]="+coord[3]); + sys.puts("coord[4]="+coord[4]); + sys.puts("coord[5]="+coord[5]); + sys.puts("coord.sx="+coord.sx); + sys.puts("coord.sy="+coord.sy); + sys.puts("coord.r="+coord.r); + sys.puts("coord.tx="+coord.tx); + sys.puts("coord.ty="+coord.ty); } loadSVG.prototype.parseRect=function(accu_matrix,coord, id, n) @@ -896,11 +949,23 @@ var trans = n.attr('transform'); var paint; var tcoord = this.mb_rt.coord_new(coord); + tcoord.node = n; + n.coord = tcoord; + this._check_duplicate_src(n,tcoord); var style = n.attr('style'); if (trans) parseTransform(tcoord,trans.value()); + else { + tcoord.sx = 1; + tcoord.sy = 1; + tcoord.r = 0; + tcoord.tx = 0; + tcoord.ty = 0; + } + + var rect = this.mb_rt.rect_new(x,y,w,h,10, 10); tcoord.add_shape(rect); @@ -949,6 +1014,18 @@ this.parseGroup(m,root,id, n) } +loadSVG.prototype._check_duplicate_src=function(n,coord) { + var attr = n.attr('duplicate-src'); + if (attr == null) return; + sys.puts("---->"+attr.value()); + var id = attr.value(); + try { + this.mb_rt.mbnames[id].target = coord; + } catch(e) { + sys.puts("id "+id+" is not defined"); + } +} + loadSVG.prototype.parseGroup=function(accu_matrix,root, group_id, n) { var k; var nodes = n.childNodes(); @@ -957,13 +1034,22 @@ var trans = n.attr('transform'); var accu=[1,0,0,0,1,0]; var style; + n.coord = coord; + coord.node = n; + this._check_duplicate_src(n,coord); coord.center= new Object(); coord.center.x = 10000; coord.center.y = 10000; if (trans!=null) { parseTransform(coord, trans.value()); - } + } else { + coord.sx = 1; + coord.sy = 1; + coord.r = 0; + coord.tx = 0; + coord.ty = 0; + } multiply(accu,accu_matrix); multiply(accu,coord); @@ -973,7 +1059,6 @@ sys.puts("opacity=" + style.opacity); coord.opacity=style.opacity; } - for(k in nodes) { var c = nodes[k].name(); var attr = nodes[k].attr('id'); @@ -991,6 +1076,8 @@ this.parseRect(accu_matrix,coord, id, nodes[k]); } else if (c == "image") { this.parseImage(accu_matrix,coord, id, nodes[k]); + } else if (c == "use") { + this.parseUse(accu_matrix,coord, id, nodes[k]); } } if (root.center.x > coord.center.x) @@ -999,16 +1086,106 @@ root.center.y = coord.center.y; this._set_bbox(n, coord); + // Set the group map only it is not defined before. The group might be + // redefined by the svg:use tag + if (this._groupMap[n.name()]==null) + this._groupMap[n.name()] = n; + + make_mbnames(this.mb_rt, n, coord); + return coord; +}; + +loadSVG.prototype.parseUse=function(accu_matrix,root, use_id, n) { + var k; + var nodes; + var coord = this.mb_rt.coord_new(root); + // Parse the transform and style here + var trans = n.attr('transform'); + var accu=[1,0,0,0,1,0]; + var style; + n.coord = coord; + coord.node = n; + this._check_duplicate_src(n,coord); + + coord.center= new Object(); + coord.center.x = 10000; + coord.center.y = 10000; + if (trans!=null) { + parseTransform(coord, trans.value()); + } else { + tcoord.sx = 1; + tcoord.sy = 1; + tcoord.r = 0; + tcoord.tx = 0; + tcoord.ty = 0; + + } + multiply(accu,accu_matrix); + multiply(accu,coord); + + style = {}; + parseGroupStyle(style, n); + if(style.opacity) { + sys.puts("opacity=" + style.opacity); + coord.opacity=style.opacity; + } + // For a use tag, we will duplicate the group inside it. + attr = n.attr('duplicate-src'); + if (attr != null) { + n = this._groupMap[attr.value()]; + if (n == null) { + sys.puts("Can not find object "+attr.value()); + return; + } + nodes = n.childNodes(); + for(k in nodes) { + var c = nodes[k].name(); + var attr = nodes[k].attr('id'); + var id; + if (attr) { + id = attr.value(); + } + if (c == "g") { + this.parseGroup(accu,coord, id, nodes[k]); + } else if (c == "path") { + this.parsePath(accu,coord, id, nodes[k]); + } else if (c == "text") { + 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(accu_matrix,coord, id, nodes[k]); + } else if (c == "use") { + this.parseUse(accu_matrix,coord, id, nodes[k]); + } + attr = nodes[k].attr('duplicate-src'); + if (attr == null) continue; + id = attr.value(); + try { + this.mbnames[id].target = coord; + } catch(e) { + sys.puts("id "+id+" is not defined"); + } + } + } + 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; + + this._set_bbox(n, coord); this._groupMap[n.name()] = n; make_mbnames(this.mb_rt, n, coord); }; - 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'); + n.coord = tcoord; + tcoord.node = n; + this._check_duplicate_src(n,tcoord); if (ref == null) return; if (ref.substr(0,7) == "file://") {