Sat, 04 Jun 2016 09:22:51 +0200
Code cleanup
16 | 1 | #!/usr/bin/env python |
2 | ||
3 | import logging | |
4 | import traceback | |
5 | import xml.etree.ElementTree as ET | |
6 | import simplepath | |
7 | import simpletransform | |
8 | import cubicsuperpath | |
9 | import cspsubdiv | |
10 | from bezmisc import beziersplitatt | |
11 | ||
12 | ||
13 | class svgshape(object): | |
14 | ||
15 | def __init__(self, xml_node): | |
16 | self.xml_node = xml_node | |
17 | ||
18 | def d_path(self): | |
19 | raise NotImplementedError | |
20 | ||
21 | def transformation_matrix(self): | |
22 | t = self.xml_node.get('transform') | |
23 | return simpletransform.parseTransform(t) if t is not None else None | |
24 | ||
25 | def svg_path(self): | |
26 | return "<path d=\"" + self.d_path() + "\"/>" | |
27 | ||
28 | def __str__(self): | |
29 | return self.xml_node | |
30 | ||
31 | class path(svgshape): | |
32 | def __init__(self, xml_node): | |
33 | super(path, self).__init__(xml_node) | |
34 | ||
35 | if not self.xml_node == None: | |
36 | path_el = self.xml_node | |
37 | self.d = path_el.get('d') | |
38 | else: | |
39 | self.d = None | |
40 | logging.error("path: Unable to get the attributes for %s", self.xml_node) | |
41 | ||
42 | def d_path(self): | |
43 | return self.d | |
44 | ||
45 | class rect(svgshape): | |
46 | ||
47 | def __init__(self, xml_node): | |
48 | super(rect, self).__init__(xml_node) | |
49 | ||
50 | if not self.xml_node == None: | |
51 | rect_el = self.xml_node | |
52 | self.x = float(rect_el.get('x')) if rect_el.get('x') else 0 | |
53 | self.y = float(rect_el.get('y')) if rect_el.get('y') else 0 | |
54 | self.rx = float(rect_el.get('rx')) if rect_el.get('rx') else 0 | |
55 | self.ry = float(rect_el.get('ry')) if rect_el.get('ry') else 0 | |
56 | self.width = float(rect_el.get('width')) if rect_el.get('width') else 0 | |
57 | self.height = float(rect_el.get('height')) if rect_el.get('height') else 0 | |
58 | else: | |
59 | self.x = self.y = self.rx = self.ry = self.width = self.height = 0 | |
60 | logging.error("rect: Unable to get the attributes for %s", self.xml_node) | |
61 | ||
62 | def d_path(self): | |
63 | a = list() | |
64 | a.append( ['M ', [self.x, self.y]] ) | |
65 | a.append( [' l ', [self.width, 0]] ) | |
66 | a.append( [' l ', [0, self.height]] ) | |
67 | a.append( [' l ', [-self.width, 0]] ) | |
68 | #a.append( [' l ', [self.x, self.y]] ) # CLOSE RECTANGLE! | |
69 | a.append( [' Z', []] ) | |
70 | return simplepath.formatPath(a) | |
71 | ||
72 | class ellipse(svgshape): | |
73 | ||
74 | def __init__(self, xml_node): | |
75 | super(ellipse, self).__init__(xml_node) | |
76 | ||
77 | if not self.xml_node == None: | |
78 | ellipse_el = self.xml_node | |
79 | self.cx = float(ellipse_el.get('cx')) if ellipse_el.get('cx') else 0 | |
80 | self.cy = float(ellipse_el.get('cy')) if ellipse_el.get('cy') else 0 | |
81 | self.rx = float(ellipse_el.get('rx')) if ellipse_el.get('rx') else 0 | |
82 | self.ry = float(ellipse_el.get('ry')) if ellipse_el.get('ry') else 0 | |
83 | else: | |
84 | self.cx = self.cy = self.rx = self.ry = 0 | |
85 | logging.error("ellipse: Unable to get the attributes for %s", self.xml_node) | |
86 | ||
87 | def d_path(self): | |
88 | x1 = self.cx - self.rx | |
89 | x2 = self.cx + self.rx | |
90 | p = 'M %f,%f ' % ( x1, self.cy ) + \ | |
91 | 'A %f,%f ' % ( self.rx, self.ry ) + \ | |
92 | '0 1 0 %f,%f ' % ( x2, self.cy ) + \ | |
93 | 'A %f,%f ' % ( self.rx, self.ry ) + \ | |
94 | '0 1 0 %f,%f' % ( x1, self.cy ) | |
95 | return p | |
96 | ||
97 | class circle(ellipse): | |
98 | def __init__(self, xml_node): | |
99 | super(ellipse, self).__init__(xml_node) | |
100 | ||
101 | if not self.xml_node == None: | |
102 | circle_el = self.xml_node | |
103 | self.cx = float(circle_el.get('cx')) if circle_el.get('cx') else 0 | |
104 | self.cy = float(circle_el.get('cy')) if circle_el.get('cy') else 0 | |
105 | self.rx = float(circle_el.get('r')) if circle_el.get('r') else 0 | |
106 | self.ry = self.rx | |
107 | else: | |
108 | self.cx = self.cy = self.r = 0 | |
109 | logging.error("Circle: Unable to get the attributes for %s", self.xml_node) | |
110 | ||
111 | class line(svgshape): | |
112 | ||
113 | def __init__(self, xml_node): | |
114 | super(line, self).__init__(xml_node) | |
115 | ||
116 | if not self.xml_node == None: | |
117 | line_el = self.xml_node | |
118 | self.x1 = float(line_el.get('x1')) if line_el.get('x1') else 0 | |
119 | self.y1 = float(line_el.get('y1')) if line_el.get('y1') else 0 | |
120 | self.x2 = float(line_el.get('x2')) if line_el.get('x2') else 0 | |
121 | self.y2 = float(line_el.get('y2')) if line_el.get('y2') else 0 | |
122 | else: | |
123 | self.x1 = self.y1 = self.x2 = self.y2 = 0 | |
124 | logging.error("line: Unable to get the attributes for %s", self.xml_node) | |
125 | ||
126 | def d_path(self): | |
127 | a = [] | |
128 | a.append( ['M ', [self.x1, self.y1]] ) | |
129 | a.append( ['L ', [self.x2, self.y2]] ) | |
130 | return simplepath.formatPath(a) | |
131 | ||
132 | class polycommon(svgshape): | |
133 | ||
134 | def __init__(self, xml_node, polytype): | |
135 | super(polycommon, self).__init__(xml_node) | |
136 | self.points = list() | |
137 | ||
138 | if not self.xml_node == None: | |
139 | polycommon_el = self.xml_node | |
140 | points = polycommon_el.get('points') if polycommon_el.get('points') else list() | |
141 | points = points.split() | |
142 | for pa in points: | |
143 | self.points.append(pa) | |
19 | 144 | #if polycommon_el.get('fill'): |
145 | # # Append first point to close shape | |
146 | # self.points.append(points[0]) | |
16 | 147 | else: |
148 | logging.error("polycommon: Unable to get the attributes for %s", self.xml_node) | |
149 | ||
150 | ||
151 | class polygon(polycommon): | |
152 | ||
153 | def __init__(self, xml_node): | |
154 | super(polygon, self).__init__(xml_node, 'polygon') | |
155 | ||
156 | def d_path(self): | |
157 | d = "M " + self.points[0] | |
158 | for i in range( 1, len(self.points) ): | |
159 | d += " L " + self.points[i] | |
160 | d += " Z" | |
161 | return d | |
162 | ||
163 | class polyline(polycommon): | |
164 | ||
165 | def __init__(self, xml_node): | |
166 | super(polyline, self).__init__(xml_node, 'polyline') | |
167 | ||
168 | def d_path(self): | |
169 | d = "M " + self.points[0] | |
170 | for i in range( 1, len(self.points) ): | |
171 | d += " L " + self.points[i] | |
172 | return d | |
173 | ||
174 | def point_generator(path, mat, flatness): | |
175 | simple_path = simplepath.parsePath(path) | |
176 | ||
177 | if len(simple_path) == 0: | |
178 | return | |
179 | ||
180 | startX,startY = float(simple_path[0][1][0]), float(simple_path[0][1][1]) | |
181 | yield startX, startY, False | |
182 | ||
183 | p = cubicsuperpath.parsePath(path) | |
184 | ||
185 | if mat: | |
186 | simpletransform.applyTransformToPath(mat, p) | |
187 | ||
188 | for sp in p: | |
189 | cspsubdiv.subdiv( sp, flatness) | |
190 | pen = False | |
191 | for csp in sp: | |
192 | ctrl_pt1 = csp[0] | |
193 | ctrl_pt2 = csp[1] | |
194 | end_pt = csp[2] | |
195 | yield end_pt[0], end_pt[1], pen | |
196 | if not pen: pen = True |