root/gdadin/T.py

Revision 1426, 5.7 kB (checked in by alpt, 6 months ago)

first import

  • Property svn:executable set to
Line 
1 #!/usr/bin/env python
2 #Note: taken from inkscape/extensions/simpletransform.py (with minor changes)
3 '''
4 Copyright (C) 2006 Jean-Francois Barraud, barraud@math.univ-lille1.fr
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 barraud@math.univ-lille1.fr
20
21 This code defines several functions to make handling of transform
22 attribute easier.
23 '''
24 import inkex, cubicsuperpath
25 import math, re
26
27 def parseTransform(transf,mat=[[1.0,0.0,0.0],[0.0,1.0,0.0]]):
28     if transf=="" or transf==None:
29         return(mat)
30     result=re.match("(translate|scale|rotate|skewX|skewY|matrix)\(([^)]*)\)",transf)
31 #-- translate --
32     if result.group(1)=="translate":
33         args=result.group(2).split(",")
34         dx=float(args[0])
35         if len(args)==1:
36             dy=0.0
37         else:
38             dy=float(args[1])
39         matrix=[[1,0,dx],[0,1,dy]]
40 #-- scale --
41     if result.groups(1)=="scale":
42         args=result.group(2).split(",")
43         sx=float(args[0])
44         if len(args)==1:
45             sy=sx
46         else:
47             sy=float(args[1])
48         matrix=[[sx,0,0],[0,sy,0]]
49 #-- rotate --
50     if result.groups(1)=="rotate":
51         args=result.group(2).split(",")
52         a=float(args[0])*math.pi/180
53         if len(args)==1:
54             cx,cy=(0.0,0.0)
55         else:
56             cx,cy=args[1:]
57         matrix=[[math.cos(a),-math.sin(a),cx],[math.sin(a),math.cos(a),cy]]
58 #-- skewX --
59     if result.groups(1)=="skewX":
60         a=float(result.group(2))*math.pi/180
61         matrix=[[1,math.tan(a),0],[0,1,0]]
62 #-- skewX --
63     if result.groups(1)=="skewX":
64         a=float(result.group(2))*math.pi/180
65         matrix=[[1,0,0],[math.tan(a),1,0]]
66 #-- matrix --
67     if result.group(1)=="matrix":
68         a11,a21,a12,a22,v1,v2=result.group(2).split(",")
69         matrix=[[float(a11),float(a12),float(v1)],[float(a21),float(a22),float(v2)]]
70    
71     matrix=composeTransform(mat,matrix)
72     if result.end()<len(transf):
73         return(parseTransform(transf[result.end():],matrix))
74     else:
75         return matrix
76
77 def formatTransform(mat):
78     return("matrix(%f,%f,%f,%f,%f,%f)"%(mat[0][0],mat[1][0],mat[0][1],mat[1][1],mat[0][2],mat[1][2]))
79
80 def composeTransform(M1,M2):
81     a11=M1[0][0]*M2[0][0]+M1[0][1]*M2[1][0]
82     a12=M1[0][0]*M2[0][1]+M1[0][1]*M2[1][1]
83     a21=M1[1][0]*M2[0][0]+M1[1][1]*M2[1][0]
84     a22=M1[1][0]*M2[0][1]+M1[1][1]*M2[1][1]
85
86     v1=M1[0][0]*M2[0][2]+M1[0][1]*M2[1][2]+M1[0][2]
87     v2=M1[1][0]*M2[0][2]+M1[1][1]*M2[1][2]+M1[1][2]
88     return [[a11,a12,v1],[a21,a22,v2]]
89
90 def writeTransformToNode(mat,node):
91     node.set("transform", formatTransform(mat))
92
93 def applyTransformToNode(mat,node):
94     m=parseTransform(node.get("transform"))
95     writeTransformToNode(composeTransform(mat,m), node)
96
97 def applyTransformToPoint(mat,pt):
98     x=mat[0][0]*pt[0]+mat[0][1]*pt[1]+mat[0][2]
99     y=mat[1][0]*pt[0]+mat[1][1]*pt[1]+mat[1][2]
100     pt[0]=x
101     pt[1]=y
102
103 def applyTransformToPath(mat,path):
104     for comp in path:
105         for ctl in comp:
106             for pt in ctl:
107                 applyTransformToPoint(mat,pt)
108
109 ####################################################################
110 ##-- Some functions to compute a rough bbox of a given list of objects.
111 ##-- this should be shipped out in an separate file...
112
113 def boxunion(b1,b2):
114     if b1 is None:
115         return b2
116     elif b2 is None:
117         return b1   
118     else:
119         return((min(b1[0],b2[0]),max(b1[1],b2[1]),min(b1[2],b2[2]),max(b1[3],b2[3])))
120
121 def roughBBox(path):
122     xmin,xMax,ymin,yMax=path[0][0][0][0],path[0][0][0][0],path[0][0][0][1],path[0][0][0][1]
123     for pathcomp in path:
124         for ctl in pathcomp:
125            for pt in ctl:
126                xmin=min(xmin,pt[0])
127                xMax=max(xMax,pt[0])
128                ymin=min(ymin,pt[1])
129                yMax=max(yMax,pt[1])
130     return xmin,xMax,ymin,yMax
131
132 def computeBBox(aList,mat=[[1,0,0],[0,1,0]]):
133     bbox=None
134     for node in aList:
135         m = parseTransform(node.get('transform'))
136         m = composeTransform(mat,m)
137         #TODO: text not supported!
138
139         if node.tag == inkex.addNS('rect','svg'):
140                 A=[0,0]
141                 B=[0,0]
142                 A[0] = float(node.get('x'))
143                 A[1] = float(node.get('y'))
144                 B[0] = A[0]+float(node.get('width'))
145                 B[1] = A[1]+float(node.get('height'))
146                 applyTransformToPoint(mat, A)
147                 applyTransformToPoint(mat, B)
148                 bbox = min(A[0], B[0]), max(A[0], B[0]), min(A[1], B[1]), max(A[1], B[1])
149         if node.get("d"):
150             d = node.get('d')
151             p = cubicsuperpath.parsePath(d)
152             applyTransformToPath(m,p)
153             bbox=boxunion(roughBBox(p),bbox)
154
155         if  node.tag == inkex.addNS('use','svg') or node.tag=='use':
156             refid=node.get(inkex.addNS('href','xlink'))
157             path = '//*[@id="%s"]' % refid[1:]
158             refnode = node.getroottree().xpath(path, namespaces=inkex.NSS)
159             bbox=boxunion(computeBBox(refnode,m),bbox)
160            
161         bbox=boxunion(computeBBox(node,m),bbox)
162     return bbox
Note: See TracBrowser for help on using the browser.