chiark / gitweb /
Merge branch 'SteamEngine' of github.com:daid/Cura into SteamEngine
authordaid <daid303@gmail.com>
Sat, 28 Sep 2013 14:29:36 +0000 (16:29 +0200)
committerdaid <daid303@gmail.com>
Sat, 28 Sep 2013 14:29:36 +0000 (16:29 +0200)
Cura/util/svg.py

index 9c45fba79d707b6f03763c6b93eeed505d6742d7..cd9acb540d76c96d4c6b254b2772aa3b1406f642 100644 (file)
@@ -2,245 +2,425 @@ from __future__ import absolute_import
 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
 
 import math
+import re
+import sys
+import numpy
 from xml.etree import ElementTree
 
-import profile
-
-def processRect(e):
-       x = float(e.get('x'))
-       y = float(e.get('y'))
-       width = float(e.get('width'))
-       height = float(e.get('height'))
-       return [[complex(x, -y), complex(x+width, -y), complex(x+width, -(y+height)), complex(x, -(y+height)), complex(x, -y)]]
-
-def processPath(e):
-       d = e.get('d').replace(',', ' ')
-       num = ""
-       cmd = None
-       paths = []
-       curPath = None
-       
-       p = complex(0, 0)
-       for c in d + "#":
-               if c in "-+.0123456789e":
-                       num += c
-               if c in " \t\n\r#":
-                       if len(num) > 0:
-                               param.append(float(num))
-                       num = ""
-               if c in "MmZzLlHhVvCcSsQqTtAa#":
-                       if cmd == 'M':
-                               p = complex(param[0], -param[1])
-                               curPath = None
-                               i = 2
-                               while i < len(param):
-                                       if curPath == None:
-                                               curPath = [p]
-                                               paths.append(curPath)
-                                       p = complex(param[i], -param[i+1])
-                                       curPath.append(p)
-                                       i += 2
-                       elif cmd == 'm':
-                               p += complex(param[0], -param[1])
-                               curPath = None
-                               i = 2
-                               while i < len(param):
-                                       if curPath == None:
-                                               curPath = [p]
-                                               paths.append(curPath)
-                                       p += complex(param[i], -param[i+1])
-                                       curPath.append(p)
-                                       i += 2
-                       elif cmd == 'L':
-                               if curPath == None:
-                                       curPath = [p]
-                                       paths.append(curPath)
-                               i = 0
-                               while i < len(param):
-                                       p = complex(param[i], -param[i+1])
-                                       curPath.append(p)
-                                       i += 2
-                       elif cmd == 'l':
-                               if curPath == None:
-                                       curPath = [p]
-                                       paths.append(curPath)
-                               i = 0
-                               while i < len(param):
-                                       p += complex(param[i], -param[i+1])
-                                       curPath.append(p)
-                                       i += 2
-                               curPath.append(p)
-                       elif cmd == 'C':
-                               if curPath == None:
-                                       curPath = [p]
-                                       paths.append(curPath)
-                               i = 0
-                               while i < len(param):
-                                       addCurve(curPath, p, complex(param[i], -param[i+1]), complex(param[i+2], -param[i+3]), complex(param[i+4], -param[i+5]))
-                                       p = complex(param[i+4], -param[i+5])
-                                       curPath.append(p)
-                                       i += 6
-                       elif cmd == 'c':
-                               if curPath == None:
-                                       curPath = [p]
-                                       paths.append(curPath)
-                               i = 0
-                               while i < len(param):
-                                       addCurve(curPath, p, p + complex(param[i], -param[i+1]), p + complex(param[i+2], -param[i+3]), p + complex(param[i+4], -param[i+5]))
-                                       p += complex(param[i+4], -param[i+5])
-                                       curPath.append(p)
-                                       i += 6
-                       elif cmd == 'a':
-                               if curPath == None:
-                                       curPath = [p]
-                                       paths.append(curPath)
-                               i = 0
-                               print(param)
-                               while i < len(param):
-                                       endPoint = p + complex(param[i+5], -param[i+6])
-                                       addArc(curPath, p, endPoint, complex(param[i], param[i+1]), param[i+2], param[i+3], param[i+4])
-                                       p = endPoint
-                                       curPath.append(p)
-                                       i += 7
-                       elif cmd == 'Z' or cmd == 'z':
-                               curPath.append(curPath[0])
-                       elif cmd != None:
-                               print(cmd)
-                       cmd = c
-                       param = []
-       return paths
-
-def interpolate(p0, p1, f):
-       return complex(p0.real + (p1.real - p0.real) * f, p0.imag + (p1.imag - p0.imag) * f)
-
-def addCurve(path, p0, q0, q1, p1):
-       oldPoint = p0
-       for n in xrange(0, 100):
-               k = n / 100.0
-               r0 = interpolate(p0, q0, k);
-               r1 = interpolate(q0, q1, k);
-               r2 = interpolate(q1, p1, k);
-               b0 = interpolate(r0, r1, k);
-               b1 = interpolate(r1, r2, k);
-               s = interpolate(b0, b1, k);
-               if abs(s - oldPoint) > 1.0:
-                       path.append(s)
-                       oldPoint = s
-
-def addArc(path, begin, end, radius, xAxisRotation, largeArcFlag, sweepFlag):
-       xAxisRotationComplex = complex(math.cos(math.radians(xAxisRotation)), math.sin(math.radians(xAxisRotation)))
-       reverseXAxisRotationComplex = complex(xAxisRotationComplex.real, -xAxisRotationComplex.imag)
-       beginRotated = begin * reverseXAxisRotationComplex
-       endRotated = end * reverseXAxisRotationComplex
-       beginTransformed = complex(beginRotated.real / radius.real, beginRotated.imag / radius.imag)
-       endTransformed = complex(endRotated.real / radius.real, endRotated.imag / radius.imag)
-       midpointTransformed = 0.5 * (beginTransformed + endTransformed)
-       midMinusBeginTransformed = midpointTransformed - beginTransformed
-       midMinusBeginTransformedLength = abs(midMinusBeginTransformed)
-
-       if midMinusBeginTransformedLength > 1.0:
-               radius *= midMinusBeginTransformedLength
-               beginTransformed /= midMinusBeginTransformedLength
-               endTransformed /= midMinusBeginTransformedLength
-               midpointTransformed /= midMinusBeginTransformedLength
-               midMinusBeginTransformed /= midMinusBeginTransformedLength
-               midMinusBeginTransformedLength = 1.0
-       midWiddershinsTransformed = complex(-midMinusBeginTransformed.imag, midMinusBeginTransformed.real)
-       midWiddershinsLengthSquared = 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength
-       if midWiddershinsLengthSquared < 0.0:
-               midWiddershinsLengthSquared = 0.0
-       midWiddershinsLength = math.sqrt(midWiddershinsLengthSquared)
-       midWiddershinsTransformed *= midWiddershinsLength / abs(midWiddershinsTransformed)
-       centerTransformed = midpointTransformed
-       if largeArcFlag == sweepFlag:
-               centerTransformed -= midWiddershinsTransformed
-       else:
-               centerTransformed += midWiddershinsTransformed
-       beginMinusCenterTransformed = beginTransformed - centerTransformed
-       beginMinusCenterTransformedLength = abs(beginMinusCenterTransformed)
-       if beginMinusCenterTransformedLength <= 0.0:
-               return end
-       beginAngle = math.atan2(beginMinusCenterTransformed.imag, beginMinusCenterTransformed.real)
-       endMinusCenterTransformed = endTransformed - centerTransformed
-       angleDifference = getAngleDifferenceByComplex(endMinusCenterTransformed, beginMinusCenterTransformed)
-       if sweepFlag:
-               if angleDifference < 0.0:
-                       angleDifference += 2.0 * math.pi
-       else:
-               if angleDifference > 0.0:
-                       angleDifference -= 2.0 * math.pi
-
-       center = complex(centerTransformed.real * radius.real, centerTransformed.imag * radius.imag) * xAxisRotationComplex
-       for side in xrange(1, 32):
-               a = beginAngle + float(side) * math.pi * 2 / 32
-               circumferential = complex(math.cos(a) * radius.real, math.sin(a) * radius.imag) * beginMinusCenterTransformedLength
-               point = center + circumferential * xAxisRotationComplex
-               path.append(point)
-
-def getAngleDifferenceByComplex( subtractFromComplex, subtractComplex ):
-       subtractComplexMirror = complex( subtractComplex.real , - subtractComplex.imag )
-       differenceComplex = subtractComplexMirror * subtractFromComplex
-       return math.atan2( differenceComplex.imag, differenceComplex.real )
-
-
-def movePath(p, offset):
-       return map(lambda _p: _p - offset, p)
+def applyTransformString(matrix, transform):
+       s = transform.find('(')
+       e = transform.find(')')
+       if s < 0 or e < 0:
+               print 'Unknown transform: %s' % (transform)
+               return matrix
+       tag = transform[:s]
+       data = map(float, re.split('[ \t,]+', transform[s+1:e].strip()))
+       if tag == 'matrix' and len(data) == 6:
+               return matrix * numpy.matrix([[data[0],data[1],0],[data[2],data[3],0],[data[4],data[5],1]], numpy.float64)
+       elif tag == 'translate' and len(data) == 1:
+               return matrix * numpy.matrix([[1,0,data[0]],[0,1,0],[0,0,1]], numpy.float64)
+       elif tag == 'translate' and len(data) == 2:
+               return matrix * numpy.matrix([[1,0,0],[0,1,0],[data[0],data[1],1]], numpy.float64)
+       elif tag == 'scale' and len(data) == 1:
+               return matrix * numpy.matrix([[data[0],0,0],[0,data[0],0],[0,0,1]], numpy.float64)
+       elif tag == 'scale' and len(data) == 2:
+               return matrix * numpy.matrix([[data[0],0,0],[0,data[1],0],[0,0,1]], numpy.float64)
+       elif tag == 'rotate' and len(data) == 1:
+               r = math.radians(data[0])
+               return matrix * numpy.matrix([[math.cos(r),math.sin(r),0],[-math.sin(r),math.cos(r),0],[0,0,1]], numpy.float64)
+       elif tag == 'skewX' and len(data) == 1:
+               return matrix * numpy.matrix([[1,0,0],[math.tan(data[0]),1,0],[0,0,1]], numpy.float64)
+       elif tag == 'skewY' and len(data) == 1:
+               return matrix * numpy.matrix([[1,math.tan(data[0]),0],[0,1,0],[0,0,1]], numpy.float64)
+       print 'Unknown transform: %s' % (transform)
+       return matrix
+
+class Path(object):
+       LINE = 0
+       ARC = 1
+       CURVE = 2
+
+       def __init__(self, x, y, matrix):
+               self._matrix = matrix
+               self._relMatrix = numpy.matrix([[matrix[0,0],matrix[0,1]], [matrix[1,0],matrix[1,1]]])
+               self._startPoint = complex(x, y)
+               self._points = []
+
+       def addLineTo(self, x, y):
+               self._points.append({'type': Path.LINE, 'p': complex(x, y)})
+
+       def addArcTo(self, x, y, rot, rx, ry, large, sweep):
+               self._points.append({
+                       'type': Path.ARC,
+                       'p': complex(x, y),
+                       'rot': rot,
+                       'radius': complex(rx, ry),
+                       'large': large,
+                       'sweep': sweep
+               })
+
+       def addCurveTo(self, x, y, cp1x, cp1y, cp2x, cp2y):
+               self._points.append({
+                       'type': Path.CURVE,
+                       'p': complex(x, y),
+                       'cp1': complex(cp1x, cp1y),
+                       'cp2': complex(cp2x, cp2y)
+               })
+
+       def closePath(self):
+               self._points.append({'type': Path.LINE, 'p': self._startPoint})
+
+       def getPoints(self):
+               pointList = [self._m(self._startPoint)]
+               p1 = self._startPoint
+               for p in self._points:
+                       if p['type'] == Path.LINE:
+                               p1 = p['p']
+                               pointList.append(self._m(p1))
+                       elif p['type'] == Path.ARC:
+                               p2 = p['p']
+                               rot = math.radians(p['rot'])
+                               r = p['radius']
+
+                               #http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
+                               diff = (p1 - p2) / 2
+                               p1alt = diff #TODO: apply rot
+                               p2alt = -diff #TODO: apply rot
+                               rx2 = r.real*r.real
+                               ry2 = r.imag*r.imag
+                               x1alt2 = p1alt.real*p1alt.real
+                               y1alt2 = p1alt.imag*p1alt.imag
+
+                               f = x1alt2 / rx2 + y1alt2 / ry2
+                               if f >= 1.0:
+                                       r *= math.sqrt(f+0.000001)
+                                       rx2 = r.real*r.real
+                                       ry2 = r.imag*r.imag
+
+                               f = math.sqrt((rx2*ry2 - rx2*y1alt2 - ry2*x1alt2) / (rx2*y1alt2+ry2*x1alt2))
+                               if p['large'] == p['sweep']:
+                                       f = -f
+                               cAlt = f * complex(r.real*p1alt.imag/r.imag, -r.imag*p1alt.real/r.real)
+
+                               c = cAlt + (p1 + p2) / 2 #TODO: apply rot
+
+                               a1 = math.atan2((p1alt.imag - cAlt.imag) / r.imag, (p1alt.real - cAlt.real) / r.real)
+                               a2 = math.atan2((p2alt.imag - cAlt.imag) / r.imag, (p2alt.real - cAlt.real) / r.real)
+
+                               #if a1 > a2:
+                               #       a2 += math.pi * 2
+                               large = abs(a2 - a1) > math.pi
+                               if large != p['large']:
+                                       if a1 < a2:
+                                               a1 += math.pi * 2
+                                       else:
+                                               a2 += math.pi * 2
+
+                               for n in xrange(0, 16):
+                                       pointList.append(self._m(c + complex(math.cos(a1 + n*(a2-a1)/16) * r.real, math.sin(a1 + n*(a2-a1)/16) * r.imag)))
+
+                               pointList.append(self._m(p2))
+                               p1 = p2
+                       elif p['type'] == Path.CURVE:
+                               p1_ = self._m(p1)
+                               p2 = self._m(p['p'])
+                               cp1 = self._m(p['cp1'])
+                               cp2 = self._m(p['cp2'])
+
+                               for n in xrange(0, 10):
+                                       f = n / 10.0
+                                       g = 1.0-f
+                                       point = p1_*g*g*g + cp1*3.0*g*g*f + cp2*3.0*g*f*f + p2*f*f*f
+                                       pointList.append(point)
+
+                               pointList.append(p2)
+                               p1 = p['p']
+
+               return pointList
+
+       def getSVGPath(self):
+               p0 = self._m(self._startPoint)
+               ret = 'M %f %f ' % (p0.real, p0.imag)
+               for p in self._points:
+                       if p['type'] == Path.LINE:
+                               p0 = self._m(p['p'])
+                               ret += 'L %f %f' % (p0.real, p0.imag)
+                       elif p['type'] == Path.ARC:
+                               p0 = self._m(p['p'])
+                               radius = p['radius']
+                               ret += 'A %f %f 0 %d %d %f %f' % (radius.real, radius.imag, p['large'], p['sweep'], p0.real, p0.imag)
+                       elif p['type'] == Path.CURVE:
+                               p0 = self._m(p['p'])
+                               cp1 = self._m(p['cp1'])
+                               cp2 = self._m(p['cp2'])
+                               ret += 'C %f %f %f %f %f %f' % (cp1.real, cp1.imag, cp2.real, cp2.imag, p0.real, p0.imag)
+
+               return ret
+
+       def _m(self, p):
+               tmp = numpy.matrix([p.real, p.imag, 1], numpy.float64) * self._matrix
+               return complex(tmp[0,0], tmp[0,1])
+       def _r(self, p):
+               tmp = numpy.matrix([p.real, p.imag], numpy.float64) * self._relMatrix
+               return complex(tmp[0,0], tmp[0,1])
 
 class SVG(object):
        def __init__(self, filename):
-               tagProcess = {}
-               tagProcess['rect'] = processRect
-               tagProcess['path'] = processPath
+               self.tagProcess = {}
+               self.tagProcess['rect'] = self._processRectTag
+               self.tagProcess['line'] = self._processLineTag
+               self.tagProcess['polyline'] = self._processPolylineTag
+               self.tagProcess['polygon'] = self._processPolygonTag
+               self.tagProcess['elipse'] = self._processPolygonTag
+               self.tagProcess['circle'] = self._processCircleTag
+               self.tagProcess['ellipse'] = self._processEllipseTag
+               self.tagProcess['path'] = self._processPathTag
+               self.tagProcess['g'] = self._processGTag
+               self.tagProcess['a'] = self._processGTag
+               self.tagProcess['text'] = None #No text implementation yet
+               self.tagProcess['image'] = None
+               self.tagProcess['metadata'] = None
+               self.tagProcess['defs'] = None
+               self.tagProcess['title'] = None
+               self.tagProcess['animate'] = None
+               self.tagProcess['set'] = None
+               self.tagProcess['script'] = None
+
+               #From Inkscape
+               self.tagProcess['namedview'] = None
+               #From w3c testsuite
+               self.tagProcess['SVGTestCase'] = None
 
                self.paths = []
-               for e in ElementTree.parse(open(filename, "r")).getiterator():
+               f = open(filename, "r")
+               self._processGTag(ElementTree.parse(f).getroot(), numpy.matrix(numpy.identity(3, numpy.float64)))
+               f.close()
+
+       def _processGTag(self, tag, baseMatrix):
+               for e in tag:
+                       if e.get('transform') is None:
+                               matrix = baseMatrix
+                       else:
+                               matrix = applyTransformString(baseMatrix, e.get('transform'))
                        tag = e.tag[e.tag.find('}')+1:]
-                       if not tag in tagProcess:
-                               #print 'unknown tag: %s' % (tag)
-                               continue
-                       self.paths.extend(tagProcess[tag](e))
-       
-       def center(self, centerPoint):
-               offset = complex(0, 0)
-               n = 0
-               for path in self.paths:
-                       for point in path:
-                               offset += point
-                               n += 1
-               offset /= n
-               offset -= centerPoint
-               
-               self.paths = [movePath(p, offset) for p in self.paths]
+                       if not tag in self.tagProcess:
+                               print 'unknown tag: %s' % (tag)
+                       elif self.tagProcess[tag] is not None:
+                               self.tagProcess[tag](e, matrix)
+
+       def _processLineTag(self, tag, matrix):
+               x1 = float(tag.get('x1', 0))
+               y1 = float(tag.get('y1', 0))
+               x2 = float(tag.get('x2', 0))
+               y2 = float(tag.get('y2', 0))
+               p = Path(x1, y1, matrix)
+               p.addLineTo(x2, y2)
+               self.paths.append(p)
+
+       def _processPolylineTag(self, tag, matrix):
+               values = map(float, re.split('[, \t]+', tag.get('points', '').replace('-', ' -').strip()))
+               p = Path(values[0], values[1], matrix)
+               for n in xrange(2, len(values)-1, 2):
+                       p.addLineTo(values[n], values[n+1])
+               self.paths.append(p)
+
+       def _processPolygonTag(self, tag, matrix):
+               values = map(float, re.split('[, \t]+', tag.get('points', '').replace('-', ' -').strip()))
+               p = Path(values[0], values[1], matrix)
+               for n in xrange(2, len(values)-1, 2):
+                       p.addLineTo(values[n], values[n+1])
+               p.closePath()
+               self.paths.append(p)
+
+       def _processCircleTag(self, tag, matrix):
+               cx = float(tag.get('cx', 0))
+               cy = float(tag.get('cy', 0))
+               r = float(tag.get('r', 0))
+               p = Path(cx-r, cy, matrix)
+               p.addArcTo(cx+r, cy, 0, r, r, False, False)
+               p.addArcTo(cx-r, cy, 0, r, r, False, False)
+               self.paths.append(p)
+
+       def _processEllipseTag(self, tag, matrix):
+               cx = float(tag.get('cx', 0))
+               cy = float(tag.get('cy', 0))
+               rx = float(tag.get('rx', 0))
+               ry = float(tag.get('rx', 0))
+               p = Path(cx-rx, cy, matrix)
+               p.addArcTo(cx+rx, cy, 0, rx, ry, False, False)
+               p.addArcTo(cx-rx, cy, 0, rx, ry, False, False)
+               self.paths.append(p)
+
+       def _processRectTag(self, tag, matrix):
+               x = float(tag.get('x', 0))
+               y = float(tag.get('y', 0))
+               width = float(tag.get('width', 0))
+               height = float(tag.get('height', 0))
+               if width <= 0 or height <= 0:
+                       return
+               rx = tag.get('rx')
+               ry = tag.get('ry')
+               if rx is not None or ry is not None:
+                       if ry is None:
+                               ry = rx
+                       if rx is None:
+                               rx = ry
+                       rx = float(rx)
+                       ry = float(ry)
+                       if rx > width / 2:
+                               rx = width / 2
+                       if ry > height / 2:
+                               ry = height / 2
+               else:
+                       rx = 0.0
+                       ry = 0.0
+
+               if rx > 0 and ry > 0:
+                       p = Path(x+rx, y, matrix)
+                       p.addLineTo(x+width-rx, y)
+                       p.addArcTo(x+width,y+ry, 0, rx, ry, False, True)
+                       p.addLineTo(x+width, y+height-ry)
+                       p.addArcTo(x+width-rx,y+height, 0, rx, ry, False, True)
+                       p.addLineTo(x+rx, y+height)
+                       p.addArcTo(x,y+height-ry, 0, rx, ry, False, True)
+                       p.addLineTo(x, y+ry)
+                       p.addArcTo(x+rx,y, 0, rx, ry, False, True)
+                       self.paths.append(p)
+               else:
+                       p = Path(x, y, matrix)
+                       p.addLineTo(x,y+height)
+                       p.addLineTo(x+width,y+height)
+                       p.addLineTo(x+width,y)
+                       p.closePath()
+                       self.paths.append(p)
+
+       def _processPathTag(self, tag, matrix):
+               pathString = tag.get('d', '').replace(',', ' ').replace('-', ' -')
+               x = 0
+               y = 0
+               path = None
+               for command in re.findall('[a-df-zA-DF-Z][^a-df-zA-DF-Z]*', pathString):
+                       params = re.split(' +', command[1:].strip())
+                       if len(params) > 0 and params[0] == '':
+                               params = params[1:]
+                       if len(params) > 0 and params[-1] == '':
+                               params = params[:-1]
+                       params = map(float, params)
+                       command = command[0]
+
+                       if command == 'm':
+                               x += params[0]
+                               y += params[1]
+                               path = Path(x, y, matrix)
+                               self.paths.append(path)
+                               params = params[2:]
+                               while len(params) > 1:
+                                       x += params[0]
+                                       y += params[1]
+                                       params = params[2:]
+                                       path.addLineTo(x, y)
+                       elif command == 'M':
+                               x = params[0]
+                               y = params[1]
+                               path = Path(x, y, matrix)
+                               self.paths.append(path)
+                               params = params[2:]
+                               while len(params) > 1:
+                                       x = params[0]
+                                       y = params[1]
+                                       params = params[2:]
+                                       path.addLineTo(x, y)
+                       elif command == 'l':
+                               while len(params) > 1:
+                                       x += params[0]
+                                       y += params[1]
+                                       params = params[2:]
+                                       path.addLineTo(x, y)
+                       elif command == 'L':
+                               while len(params) > 1:
+                                       x = params[0]
+                                       y = params[1]
+                                       params = params[2:]
+                                       path.addLineTo(x, y)
+                       elif command == 'h':
+                               x += params[0]
+                               path.addLineTo(x, y)
+                       elif command == 'H':
+                               x = params[0]
+                               path.addLineTo(x, y)
+                       elif command == 'v':
+                               y += params[0]
+                               path.addLineTo(x, y)
+                       elif command == 'V':
+                               y = params[0]
+                               path.addLineTo(x, y)
+                       elif command == 'a':
+                               while len(params) > 6:
+                                       x += params[5]
+                                       y += params[6]
+                                       path.addArcTo(x, y, params[2], params[0], params[1], params[3] > 0, params[4] > 0)
+                                       params = params[7:]
+                       elif command == 'A':
+                               while len(params) > 6:
+                                       x = params[5]
+                                       y = params[6]
+                                       path.addArcTo(x, y, params[2], params[0], params[1], params[3] > 0, params[4] > 0)
+                                       params = params[7:]
+                       elif command == 'c':
+                               while len(params) > 5:
+                                       c1x = x + params[0]
+                                       c1y = y + params[1]
+                                       c2x = x + params[2]
+                                       c2y = y + params[3]
+                                       x += params[4]
+                                       y += params[5]
+                                       path.addCurveTo(x, y, c1x, c1y, c2x, c2y)
+                                       params = params[6:]
+                       elif command == 'C':
+                               while len(params) > 5:
+                                       c1x = params[0]
+                                       c1y = params[1]
+                                       c2x = params[2]
+                                       c2y = params[3]
+                                       x = params[4]
+                                       y = params[5]
+                                       path.addCurveTo(x, y, c1x, c1y, c2x, c2y)
+                                       params = params[6:]
+                       elif command == 'z' or command == 'Z':
+                               path.closePath()
+                               x = path._startPoint.real
+                               y = path._startPoint.imag
+                       else:
+                               print 'Unknown path command:', command, params
+
 
 if __name__ == '__main__':
-       svg = SVG("../logo.svg")
-       f = open("../../test_export.gcode", "w")
-
-       f.write(';TYPE:CUSTOM\n')
-       f.write(profile.getAlterationFileContents('start.gcode'))
-       svg.center(complex(profile.getMachineSettingFloat('machine_width') / 2, profile.getMachineSettingFloat('machine_depth') / 2))
-
-       layerThickness = 0.4
-       filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
-       filamentArea = math.pi * filamentRadius * filamentRadius
-       lineWidth = profile.getProfileSettingFloat('nozzle_size') * 2
-
-       e = 0
-       z = layerThickness
-
-       for n in xrange(0, 20):
-               f.write("G1 Z%f F%f\n" % (z, profile.getProfileSettingFloat('max_z_speed')*60))
-               for path in svg.paths:
-                       oldPoint = path[0]
-                       extrusionMMperDist = lineWidth * layerThickness / filamentArea
-                       f.write("G1 X%f Y%f F%f\n" % (oldPoint.real, oldPoint.imag, profile.getProfileSettingFloat('travel_speed')*60))
-                       f.write("G1 F%f\n" % (profile.getProfileSettingFloat('print_speed')*60))
-                       for point in path[1:]:
-                               dist = abs(oldPoint - point)
-                               e += dist * extrusionMMperDist
-                               f.write("G1 X%f Y%f E%f\n" % (point.real, point.imag, e))
-                               oldPoint = point
-               z += layerThickness
-       f.write(profile.getAlterationFileContents('end.gcode'))
+       for n in xrange(1, len(sys.argv)):
+               print 'File: %s' % (sys.argv[n])
+               svg = SVG(sys.argv[n])
+
+       f = open("test_export.html", "w")
+
+       f.write("<!DOCTYPE html><html><body>\n")
+       f.write("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" style='width:%dpx;height:%dpx'>\n" % (1000, 1000))
+       f.write("<g fill-rule='evenodd' style=\"fill: gray; stroke:black;stroke-width:2\">\n")
+       f.write("<path d=\"")
+       for path in svg.paths:
+               points = path.getPoints()
+               f.write("M %f %f " % (points[0].real, points[0].imag))
+               for point in points[1:]:
+                       f.write("L %f %f " % (point.real, point.imag))
+       f.write("\"/>")
+       f.write("</g>\n")
+
+       f.write("<g style=\"fill: none; stroke:red;stroke-width:1\">\n")
+       f.write("<path d=\"")
+       for path in svg.paths:
+               f.write(path.getSVGPath())
+       f.write("\"/>")
+       f.write("</g>\n")
+
+       f.write("</svg>\n")
+       f.write("</body></html>")
        f.close()