#!/usr/bin/env python import xmllib, re, sys scalefactor = 4 allpaths = [] class Point: def __init__ (self, x = 0, y = 0, type = 1): self.x = x self.y = y self.type = type def __add__ (self, other): return Point (self.x + other.x, self.y + other.y, self.type) def __mul__ (self, other): return Point (self.x * other, self.y * other, self.type) def __rmul__ (self, other): return Point (self.x * other, self.y * other, self.type) def __str__ (self): return "TYPE: %d X: %d Y: %d\n" % (self.type, int (self.x*scalefactor), int (self.y*scalefactor)) class Path: def __init__(self): self.name = "Foo" self.npoints = 0 self.closed = 1 self.draw = 0 self.state = 2 self.points = [] self.curpoint = None def mkabsolute (self, p): ret = Point (self.curpoint.x + p.x, self.curpoint.y + p.y, p.type) self.curpoint = ret return ret def moveto (self, p, relative=0): if relative: p = self.mkabsolute (p) if self.points: self.points.append (Point (p.x, p.y, 3)) else: self.points.append (Point (p.x, p.y, 1)) self.closed = 0 self.state = 2 self.curpoint = self.points[-1] self.npoints = len (self.points) def closepath (self): if self.npoints % 3 == 1: self.points = self.points [:-1] self.closed = 1 self.state = 4 self.curpoint = None self.npoints = len (self.points) def lineto (self, p, relative=0): if relative: p = self.mkabsolute (p) self.curveto (self.curpoint, p, p) def curveto (self, p0, p1, p2, relative=0): if relative: p0 = self.mkabsolute (p0) p1 = self.mkabsolute (p1) p2 = self.mkabsolute (p2) self.points.append (Point (p0.x, p0.y, 2)) self.points.append (Point (p1.x, p1.y, 2)) self.points.append (Point (p2.x, p2.y, 1)) self.curpoint = self.points[-1] self.npoints = len (self.points) def endpath (self): # clean up some Gimp oddities if (not self.closed) and (self.npoints % 3 == 1): self.points.append (Point (self.points[-1].x, self.points[-1].y, 2)) self.npoints = len (self.points) def __str__ (self): if self.npoints == 0: return "" s = "Name: %s\n#POINTS: %d\nCLOSED: %d\nDRAW: %d\nSTATE: %d\n" % ( self.name, self.npoints, self.closed, self.draw, self.state ) for i in self.points: s = s + str (i) return s class PoorSVGParser (xmllib.XMLParser): def path (attr): commands = [] if attr.get ("id"): print (attr ["id"]) if attr.get ("d"): #### available commands (uppercase absolute, lowercase relative) # m Moveto # c Cubic Bezier # z Closepath # l Lineto # Not yet implemented # h Horizontal Lineto # v Vertikal Lineto # s Smooth Cubic Bezier #### Not available for Gimp: # /* non-normative reference: # http://www.icce.rug.nl/erikjan/bluefuzz/beziers/beziers/beziers.html # */ # /* raise quadratic bezier to cubic */ # x1 = (ctx->cpx + 2 * ctx->params[0]) * (1.0 / 3.0); # y1 = (ctx->cpy + 2 * ctx->params[1]) * (1.0 / 3.0); # x3 = ctx->params[2]; # y3 = ctx->params[3]; # x2 = (x3 + 2 * ctx->params[0]) * (1.0 / 3.0); # y2 = (y3 + 2 * ctx->params[1]) * (1.0 / 3.0); # q Quadratic Bezier # t Smooth Quadratic Bezier # a elliptical Arc commands = re.findall ("(?i)[mzlhvcsqta][^mzlhvcsqta]*", attr["d"]) curpath = Path () allpaths.append (curpath) for i in range (len (commands)): command = re.split ("(?:\s+,?\s*)|(?:,\s*)", commands[i]) args = map (float, command[1:]) points = [] while len(args) >= 2: points.append (Point (args[0], args[1])) args = args [2:] if command[0] == "M": if not curpath.closed: curpath = Path() allpaths.append (curpath) curpath.moveto (points[0]) if len (points) > 1: for i in points [1:]: curpath.lineto (i) if command[0] == "m": if not curpath.closed: curpath = Path() allpaths.append (curpath) curpath.moveto (points[0], 1) if len (points) > 1: for i in points [1:]: curpath.lineto (i, 1) if command[0] == "C": if len(points) % 3 == 0: while points: curpath.curveto (points[0], points[1], points[2]) points = points [3:] else: raise "Wrong Number of arguments for Curveto" if command[0] == "c": if len(points) % 3 == 0: while points: curpath.curveto (points[0], points[1], points[2], 1) points = points [3:] else: raise "Wrong Number of arguments for Curveto" if command[0] == "z" or command[0] == "Z": curpath.closepath () elements = { "path": (path, None), } def main(): psp = PoorSVGParser () psp.feed (open ("wilber5.svg").read()) for i in allpaths: i.endpath () sys.stdout.write (str(i)) if __name__ == "__main__": main() # vim: ai sw=3