X-Git-Url: https://i11git.iti.kit.edu/anon-gitweb/?p=Misc%2Fipe.git;a=blobdiff_plain;f=svgtoipe.py;fp=svgtoipe.py;h=0000000000000000000000000000000000000000;hp=45f3e986029db4a8bc924dbac7bd6b99f0eb45c3;hb=24f14753f7e282d003769de540eff1b7121497a7;hpb=4cecf266fa111411d70ef0dec81548673bbefb66 diff --git a/svgtoipe.py b/svgtoipe.py deleted file mode 100755 index 45f3e98..0000000 --- a/svgtoipe.py +++ /dev/null @@ -1,865 +0,0 @@ -#!/usr/bin/env python -# -------------------------------------------------------------------- -# convert SVG to Ipe format -# -------------------------------------------------------------------- -# -# Copyright (C) 2009-2014 Otfried Cheong -# -# svgtoipe is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# svgtoipe is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with svgtoipe; if not, you can find it at -# "http://www.gnu.org/copyleft/gpl.html", or write to the Free -# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# -------------------------------------------------------------------- - -svgtoipe_version = "20091018" - -import sys -import xml.dom.minidom as xml -from xml.dom.minidom import Node -import re -import math - -import base64 -import cStringIO - -try: - from PIL import Image - have_pil = True -except: - have_pil = False - -# -------------------------------------------------------------------- - -color_keywords = { - "black" : "rgb(0, 0, 0)", - "green" :"rgb(0, 128, 0)", - "silver" :"rgb(192, 192, 192)", - "lime" :"rgb(0, 255, 0)", - "gray" :"rgb(128, 128, 128)", - "olive" :"rgb(128, 128, 0)", - "white" :"rgb(255, 255, 255)", - "yellow" :"rgb(255, 255, 0)", - "maroon" :"rgb(128, 0, 0)", - "navy" :"rgb(0, 0, 128)", - "red" :"rgb(255, 0, 0)", - "blue" :"rgb(0, 0, 255)", - "purple" :"rgb(128, 0, 128)", - "teal" :"rgb(0, 128, 128)", - "fuchsia" :"rgb(255, 0, 255)", - "aqua" :"rgb(0, 255, 255)", -} - -attribute_names = [ "stroke", - "fill", - "stroke-opacity", - "fill-opacity", - "stroke-width", - "fill-rule", - "stroke-linecap", - "stroke-linejoin", - "stroke-dasharray", - "stroke-dashoffset", - "stroke-miterlimit", - "opacity", - "font-size" ] - -def printAttributes(n): - a = n.attributes - for i in range(a.length): - name = a.item(i).name - if name[:9] != "sodipodi:" and name[:9] != "inkscape:": - print " ", name, n.getAttribute(name) - -def parse_float(txt): - if not txt: - return None - if txt.endswith('px') or txt.endswith('pt'): - return float(txt[:-2]) - elif txt.endswith('pc'): - return 12 * float(txt[:-2]) - elif txt.endswith('mm'): - return 72.0 * float(txt[:-2]) / 25.4 - elif txt.endswith('cm'): - return 72.0 * float(txt[:-2]) / 2.54 - elif txt.endswith('in'): - return 72.0 * float(txt[:-2]) - else: - return float(txt) - -def parse_opacity(txt): - if not txt: - return None - m = int(10 * (float(txt) + 0.05)) - if m == 0: m = 1 - return 10 * m - -def parse_list(string): - return re.findall("([A-Za-z]|-?[0-9]+\.?[0-9]*(?:e-?[0-9]*)?)", string) - -def parse_style(string): - sdict = {} - for item in string.split(';'): - if ':' in item: - key, value = item.split(':') - sdict[key.strip()] = value.strip() - return sdict - -def parse_color_component(txt): - if txt.endswith("%"): - return float(txt[:-1]) / 100.0 - else: - return int(txt) / 255.0 - -def parse_color(c): - if not c or c == 'none': - return None - if c in color_keywords: - c = color_keywords[c] - m = re.match(r"rgb\(([0-9\.]+%?),\s*([0-9\.]+%?),\s*([0-9\.]+%?)\s*\)", c) - if m: - r = parse_color_component(m.group(1)) - g = parse_color_component(m.group(2)) - b = parse_color_component(m.group(3)) - return (r, g, b) - m = re.match(r"#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$", c) - if m: - r = int(m.group(1), 16) / 15.0 - g = int(m.group(2), 16) / 15.0 - b = int(m.group(3), 16) / 15.0 - return (r, g, b) - m = re.match(r"#([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])" - + r"([0-9a-fA-F][0-9a-fA-F])$", c) - if m: - r = int(m.group(1), 16) / 255.0 - g = int(m.group(2), 16) / 255.0 - b = int(m.group(3), 16) / 255.0 - return (r, g, b) - sys.stderr.write("Unknown color: %s\n" % c) - return None - -def pnext(d, n): - l = [] - while n > 0: - l.append(float(d.pop(0))) - n -= 1 - return tuple(l) - -def parse_path(out, d): - d = re.findall("([A-Za-z]|-?[0-9]+\.?[0-9]*(?:e-?[0-9]*)?)", d) - x, y = 0.0, 0.0 - xs, ys = 0.0, 0.0 - while d: - if not d[0][0] in "01234567890.-": - opcode = d.pop(0) - if opcode == 'M': - x, y = pnext(d, 2) - out.write("%g %g m\n" % (x, y)) - opcode = 'L' - elif opcode == 'm': - x1, y1 = pnext(d, 2) - x += x1 - y += y1 - out.write("%g %g m\n" % (x, y)) - opcode = 'l' - elif opcode == 'L': - x, y = pnext(d, 2) - out.write("%g %g l\n" % (x, y)) - elif opcode == 'l': - x1, y1 = pnext(d, 2) - x += x1 - y += y1 - out.write("%g %g l\n" % (x, y)) - elif opcode == 'H': - x = pnext(d, 1)[0] - out.write("%g %g l\n" % (x, y)) - elif opcode == 'h': - x += pnext(d, 1)[0] - out.write("%g %g l\n" % (x, y)) - elif opcode == 'V': - y = pnext(d, 1)[0] - out.write("%g %g l\n" % (x, y)) - elif opcode == 'v': - y += pnext(d, 1)[0] - out.write("%g %g l\n" % (x, y)) - elif opcode == 'C': - x1, y1, xs, ys, x, y = pnext(d, 6) - out.write("%g %g %g %g %g %g c\n" % (x1, y1, xs, ys, x, y)) - elif opcode == 'c': - x1, y1, xs, ys, xf, yf = pnext(d, 6) - x1 += x; y1 += y - xs += x; ys += y - x += xf; y += yf - out.write("%g %g %g %g %g %g c\n" % (x1, y1, xs, ys, x, y)) - elif opcode == 'S' or opcode == 's': - x2, y2, xf, yf = pnext(d, 4) - if opcode == 's': - x2 += x; y2 += y - xf += x; yf += y - x1 = x + (x - xs); y1 = y + (y - ys) - out.write("%g %g %g %g %g %g c\n" % (x1, y1, x2, y2, xf, yf)) - xs, ys = x2, y2 - x, y = xf, yf - elif opcode == 'Q': - xs, ys, x, y = pnext(d, 4) - out.write("%g %g %g %g q\n" % (xs, ys, x, y)) - elif opcode == 'q': - xs, ys, xf, yf = pnext(d, 4) - xs += x; ys += y - x += xf; y += yf - out.write("%g %g %g %g q\n" % (xs, ys, x, y)) - elif opcode == 'T' or opcode == 't': - xf, yf = pnext(d, 2) - if opcode == 't': - xf += x; yf += y - x1 = x + (x - xs); y1 = y + (y - ys) - out.write("%g %g %g %g q\n" % (x1, y1, xf, yf)) - xs, ys = x1, y1 - x, y = xf, yf - elif opcode == 'A' or opcode == 'a': - rx, ry, phi, large_arc, sweep, x2, y2 = pnext(d, 7) - if opcode == 'a': - x2 += x; y2 += y - draw_arc(out, x, y, rx, ry, phi, large_arc, sweep, x2, y2) - x, y = x2, y2 - elif opcode in 'zZ': - out.write("h\n") - else: - sys.stderr.write("Unrecognised opcode: %s\n" % opcode) - -def parse_transformation(txt): - d = re.findall("[a-zA-Z]+\([^)]*\)", txt) - m = Matrix() - while d: - m1 = Matrix(d.pop(0)) - m = m * m1 - return m - -def get_gradientTransform(n): - if n.hasAttribute("gradientTransform"): - return parse_transformation(n.getAttribute("gradientTransform")) - return Matrix() - -def parse_transform(n): - if n.hasAttribute("transform"): - return parse_transformation(n.getAttribute("transform")) - return None - -# Convert from endpoint to center parameterization -# www.w3.org/TR/2003/REC-SVG11-20030114/implnote.html#ArcImplementationNotes -def draw_arc(out, x1, y1, rx, ry, phi, large_arc, sweep, x2, y2): - phi = math.pi * phi / 180.0 - cp = math.cos(phi); sp = math.sin(phi) - dx = .5 * (x1 - x2); dy = .5 * (y1 - y2) - x1p = cp * dx + sp * dy; y1p = -sp * dx + cp * dy - r2 = (((rx * ry)**2 - (rx * y1p)**2 - (ry * x1p)**2)/ - ((rx * y1p)**2 + (ry * x1p)**2)) - if r2 < 0: r2 = 0 - r = math.sqrt(r2) - if large_arc == sweep: - r = -r - cxp = r * rx * y1p / ry; cyp = -r * ry * x1p / rx - cx = cp * cxp - sp * cyp + .5 * (x1 + x2) - cy = sp * cxp + cp * cyp + .5 * (y1 + y2) - m = Matrix([rx, 0, 0, ry, 0, 0]) - m = Matrix([cp, sp, -sp, cp, cx, cy]) * m - if sweep == 0: - m = m * Matrix([1, 0, 0, -1, 0, 0]) - out.write("%s %g %g a\n" % (str(m), x2, y2)) - -# -------------------------------------------------------------------- - -class Matrix(object): - - # Default is identity matrix - def __init__(self, string = None): - self.values = [1, 0, 0, 1, 0, 0] - if not string or string == "": - return - if isinstance(string, list): - self.values = string - return - mat = re.match(r"([a-zA-Z]+)\(([^)]*)\)$", string) - if not mat: - sys.stderr.write("Unknown transform: %s\n" % string) - op = mat.group(1) - d = [float(x) for x in parse_list(mat.group(2))] - if op == "matrix": - self.values = d - elif op == "translate": - if len(d) == 1: d.append(0.0) - self.values = [1, 0, 0, 1, d[0], d[1]] - elif op == "scale": - if len(d) == 1: d.append(d[0]) - sx, sy = d - self.values = [sx, 0, 0, sy, 0, 0] - elif op == "rotate": - phi = math.pi * d[0] / 180.0 - self.values = [math.cos(phi), math.sin(phi), - -math.sin(phi), math.cos(phi), 0, 0] - elif op == "skewX": - tphi = math.tan(math.pi * d[0] / 180.0) - self.values = [1, 0, tphi, 1, 0, 0] - elif op == "skewY": - tphi = math.tan(math.pi * d[0] / 180.0) - self.values = [1, tphi, 0, 1, 0, 0] - else: - sys.stderr.write("Unknown transform: %s\n" % string) - - def __call__(self, other): - return (self.values[0]*other[0] + self.values[2]*other[1] + self.values[4], - self.values[1]*other[0] + self.values[3]*other[1] + self.values[5]) - - def inverse(self): - d = float(self.values[0]*self.values[3] - self.values[1]*self.values[2]) - return Matrix([self.values[3]/d, -self.values[1]/d, - -self.values[2]/d, self.values[0]/d, - (self.values[2]*self.values[5] - - self.values[3]*self.values[4])/d, - (self.values[1]*self.values[4] - - self.values[0]*self.values[5])/d]) - - def __mul__(self, other): - a, b, c, d, e, f = self.values - u, v, w, x, y, z = other.values - return Matrix([a*u + c*v, b*u + d*v, a*w + c*x, - b*w + d*x, a*y + c*z + e, b*y + d*z + f]) - - def __str__(self): - a, b, c, d, e, f = self.values - return "%g %g %g %g %g %g" % (a, b, c, d, e, f) - -# -------------------------------------------------------------------- - -class Svg(): - - def __init__(self, fname): - self.dom = xml.parse(fname) - attr = { } - for a in attribute_names: - attr[a] = None - self.attributes = [ attr ] - self.defs = { } - for n in self.dom.childNodes: - if n.nodeType == Node.ELEMENT_NODE and n.tagName == "svg": - if n.hasAttribute("viewBox"): - x, y, w, h = [float(x) for x in parse_list(n.getAttribute("viewBox"))] - self.width = w - self.height = h - self.origin = (x, y) - else: - self.width = parse_float(n.getAttribute("width")) - self.height = parse_float(n.getAttribute("height")) - self.origin = (0, 0) - self.root = n - return - -# -------------------------------------------------------------------- - - def parse_svg(self, outname): - self.out = open(outname, "w") - self.out.write('\n') - self.out.write('\n') - self.out.write('\n' % - svgtoipe_version) - self.out.write('\n') - self.out.write(('\n') % - (self.width, self.height, self.width, self.height)) - for t in range(10, 100, 10): - self.out.write('\n' % (t, t)) - # set SVG defaults - self.out.write('\n') - self.out.write('\n') - # collect definitions - for n in self.root.childNodes: - if n.nodeType != Node.ELEMENT_NODE: - continue - if hasattr(self, "def_" + n.tagName): - getattr(self, "def_" + n.tagName)(n) - # write definitions into stylesheet - if len(self.defs) > 0: - self.out.write('\n') - for k in self.defs: - if self.defs[k][0] == "linearGradient": - self.write_linear_gradient(k) - elif self.defs[k][0] == "radialGradient": - self.write_radial_gradient(k) - self.out.write('\n') - # start real data - self.out.write('\n') - m = Matrix([1, 0, 0, 1, 0, self.height / 2.0]) - m = m * Matrix([1, 0, 0, -1, 0, 0]) - m = m * Matrix([1, 0, 0, 1, - -self.origin[0], -(self.origin[1] + self.height / 2.0)]) - self.out.write('\n' % str(m)) - for n in self.root.childNodes: - if n.nodeType != Node.ELEMENT_NODE: - continue - if hasattr(self, "node_" + n.tagName): - getattr(self, "node_" + n.tagName)(n) - else: - sys.stderr.write("Unhandled node: %s\n" % n.tagName) - self.out.write('\n') - self.out.write('\n') - self.out.write('\n') - self.out.close() - -# -------------------------------------------------------------------- - - def write_linear_gradient(self, k): - typ, x1, x2, y1, y2, stops, matrix = self.defs[k] - self.out.write('\n' % (x1, y1, x2, y2)) - for s in stops: - offset, color = s - self.out.write(' \n' % - (offset, color[0], color[1], color[2])) - self.out.write('\n') - - def write_radial_gradient(self, k): - typ, cx, cy, r, fx, fy, stops, matrix = self.defs[k] - self.out.write('\n' % (fx, fy, 0, cx, cy, r)) - for s in stops: - offset, color = s - self.out.write(' \n' % - (offset, color[0], color[1], color[2])) - self.out.write('\n') - - def get_stops(self, n): - stops = [] - for m in n.childNodes: - if m.nodeType != Node.ELEMENT_NODE: - continue - if m.tagName != "stop": - continue # should not happen - offs = m.getAttribute("offset") - if offs.endswith("%"): - offs = float(offs[:-1]) / 100.0 - else: - offs = float(offs) - color = parse_color(m.getAttribute("stop-color")) - if m.hasAttribute("style"): - sdict = parse_style(m.getAttribute("style")) - if "stop-color" in sdict: - color = parse_color(sdict["stop-color"]) - stops.append((offs, color)) - if len(stops) == 0: - if n.hasAttribute("xlink:href"): - ref = n.getAttribute("xlink:href") - if ref.startswith("#") and ref[1:] in self.defs: - stops = self.defs[ref[1:]][5] - return stops - - def def_linearGradient(self, n): - #printAttributes(n) - kid = n.getAttribute("id") - x1 = 0; y1 = 0 - x2 = self.width; y2 = self.height - if n.hasAttribute("x1"): - s = n.getAttribute("x1") - if s.endswith("%"): - x1 = self.width * float(s[:-1]) / 100.0 - else: - x1 = parse_float(s) - if n.hasAttribute("x2"): - s = n.getAttribute("x2") - if s.endswith("%"): - x2 = self.width * float(s[:-1]) / 100.0 - else: - x2 = parse_float(s) - if n.hasAttribute("y1"): - s = n.getAttribute("y1") - if s.endswith("%"): - y1 = self.width * float(s[:-1]) / 100.0 - else: - y1 = parse_float(s) - if n.hasAttribute("y2"): - s = n.getAttribute("y2") - if s.endswith("%"): - y2 = self.width * float(s[:-1]) / 100.0 - else: - y2 = parse_float(s) - matrix = get_gradientTransform(n) - stops = self.get_stops(n) - self.defs[kid] = ("linearGradient", x1, x2, y1, y2, stops, matrix) - - def def_radialGradient(self, n): - #printAttributes(n) - kid = n.getAttribute("id") - cx = "50%"; cy = "50%"; r = "50%" - if n.hasAttribute("cx"): - cx = n.getAttribute("cx") - if cx.endswith("%"): - cx = self.width * float(cx[:-1]) / 100.0 - else: - cx = parse_float(cx) - if n.hasAttribute("cy"): - cy = n.getAttribute("cy") - if cy.endswith("%"): - cy = self.width * float(cy[:-1]) / 100.0 - else: - cy = parse_float(cy) - if n.hasAttribute("r"): - r = n.getAttribute("r") - if r.endswith("%"): - r = self.width * float(r[:-1]) / 100.0 - else: - r = parse_float(r) - if n.hasAttribute("fx"): - s = n.getAttribute("fx") - if s.endswith("%"): - fx = self.width * float(s[:-1]) / 100.0 - else: - fx = parse_float(s) - else: - fx = cx - if n.hasAttribute("fy"): - s = n.getAttribute("fy") - if s.endswith("%"): - fy = self.width * float(s[:-1]) / 100.0 - else: - fy = parse_float(s) - else: - fy = cy - matrix = get_gradientTransform(n) - stops = self.get_stops(n) - self.defs[kid] = ("radialGradient", cx, cy, r, fx, fy, stops, matrix) - - def def_clipPath(self, node): - kid = node.getAttribute("id") - # only a single path is implemented - for n in node.childNodes: - if n.nodeType != Node.ELEMENT_NODE or n.tagName != "path": - continue - m = parse_transform(n) - d = n.getAttribute("d") - output = cStringIO.StringIO() - parse_path(output, d) - path = output.getvalue() - output.close() - self.defs[kid] = ("clipPath", m, path) - return - - def def_g(self, group): - for n in group.childNodes: - if n.nodeType != Node.ELEMENT_NODE: - continue - if hasattr(self, "def_" + n.tagName): - getattr(self, "def_" + n.tagName)(n) - - def def_defs(self, node): - self.def_g(node) - -# -------------------------------------------------------------------- - - def parse_attributes(self, n): - pattr = self.attributes[-1] - attr = { } - for a in attribute_names: - if n.hasAttribute(a): - attr[a] = n.getAttribute(a) - else: - attr[a] = pattr[a] - if n.hasAttribute("style"): - sdict = parse_style(n.getAttribute("style")) - for a in attribute_names: - if a in sdict: - attr[a] = sdict[a] - return attr - - def write_pathattributes(self, a): - stroke = parse_color(a["stroke"]) - if stroke: - self.out.write(' stroke="%g %g %g"' % stroke) - fill = a["fill"] - if fill and fill.startswith("url("): - mat = re.match("url\(#([^)]+)\).*", fill) - if mat: - grad = mat.group(1) - if grad in self.defs and (self.defs[grad][0] == "linearGradient" or - self.defs[grad][0] == "radialGradient"): - self.out.write(' fill="1" gradient="g%s"' % grad) - else: - fill = parse_color(a["fill"]) - if fill: - self.out.write(' fill="%g %g %g"' % fill) - opacity = parse_opacity(a["opacity"]) - fill_opacity = parse_opacity(a["fill-opacity"]) - stroke_opacity = parse_opacity(a["stroke-opacity"]) - if fill and fill_opacity: - opacity = fill_opacity - if not fill and stroke and stroke_opacity: - opacity = stroke_opacity - if opacity and opacity != 100: - self.out.write(' opacity="%d%%"' % opacity) - stroke_width = parse_float(a["stroke-width"]) - if a["stroke-width"]: - self.out.write(' pen="%g"' % stroke_width) - if a["fill-rule"] == "nonzero": - self.out.write(' fillrule="wind"') - k = {"butt" : 0, "round" : 1, "square" : 2 } - if a["stroke-linecap"] in k: - self.out.write(' cap="%d"' % k[a["stroke-linecap"]]) - k = {"miter" : 0, "round" : 1, "bevel" : 2 } - if a["stroke-linejoin"] in k: - self.out.write(' join="%d"' % k[a["stroke-linejoin"]]) - dasharray = a["stroke-dasharray"] - dashoffset = a["stroke-dashoffset"] - if dasharray and dashoffset and dasharray != "none": - d = parse_list(dasharray) - off = parse_float(dashoffset) - self.out.write(' dash="[%s] %g"' % (" ".join(d), off)) - -# -------------------------------------------------------------------- - - def node_g(self, group): - # printAttributes(group) - attr = self.parse_attributes(group) - self.attributes.append(attr) - self.out.write('\n') - for n in group.childNodes: - if n.nodeType != Node.ELEMENT_NODE: - continue - if hasattr(self, "node_" + n.tagName): - getattr(self, "node_" + n.tagName)(n) - else: - sys.stderr.write("Unhandled node: %s\n" % n.tagName) - self.out.write('\n') - self.attributes.pop() - - def collect_text(self, root): - for n in root.childNodes: - if n.nodeType == Node.TEXT_NODE: - self.text += n.data - if n.nodeType != Node.ELEMENT_NODE: - continue - if n.tagName == "tspan": # recurse - self.collect_text(n) - - def node_text(self, t): - if not t.hasAttribute("x") or not t.hasAttribute("y"): - sys.stderr.write("Text without coordinates ignored\n") - return - x = float(t.getAttribute("x")) - y = float(t.getAttribute("y")) - attr = self.parse_attributes(t) - self.out.write('%s\n' % self.text.encode("UTF-8")) - - def node_image(self, node): - if not have_pil: - sys.stderr.write("No Python image library, ignored\n") - return - href = node.getAttribute("xlink:href") - if not href.startswith("data:image/png;base64,"): - sys.stderr.write("Image ignored, href = %s...\n" % href[:40]) - return - x = float(node.getAttribute("x")) - y = float(node.getAttribute("y")) - w = float(node.getAttribute("width")) - h = float(node.getAttribute("height")) - clipped = False - if node.hasAttribute("clip-path"): - mat = re.match("url\(#([^)]+)\).*", node.getAttribute("clip-path")) - if mat: - cp = mat.group(1) - if cp in self.defs and self.defs[cp][0] == "clipPath": - cp, m, path = self.defs[cp] - clipped = True - self.out.write('\n' % (str(m), path)) - self.out.write('\n' % str(m.inverse())) - self.out.write(' \n') - if True: - data = cStringIO.StringIO() - for pixel in image.getdata(): - data.write("%c%c%c" % pixel[:3]) - self.out.write(base64.b64encode(data.getvalue())) - data.close() - else: - count = 0 - for pixel in image.getdata(): - self.out.write("%02x%02x%02x" % pixel[:3]) - count += 1 - if count == 10: - self.out.write("\n") - count = 0 - fin.close() - self.out.write('\n') - if clipped: - self.out.write('\n\n') - - # handled in def pass - def node_linearGradient(self, n): - pass - - def node_radialGradient(self, n): - pass - - def node_rect(self, n): - attr = self.parse_attributes(n) - self.out.write('\n') - x = float(n.getAttribute("x")) - y = float(n.getAttribute("y")) - w = float(n.getAttribute("width")) - h = float(n.getAttribute("height")) - self.out.write("%g %g m %g %g l %g %g l %g %g l h\n" % - (x, y, x + w, y, x + w, y + h, x, y + h)) - self.out.write('\n') - - def node_circle(self, n): - self.out.write('\n') - cx = float(n.getAttribute("cx")) - cy = float(n.getAttribute("cy")) - r = float(n.getAttribute("r")) - self.out.write("%g 0 0 %g %g %g e\n" % (r, r, cx, cy)) - self.out.write('\n') - - def node_ellipse(self, n): - self.out.write('\n') - cx = 0 - cy = 0 - if n.hasAttribute("cx"): - cx = float(n.getAttribute("cx")) - if n.hasAttribute("cy"): - cy = float(n.getAttribute("cy")) - rx = float(n.getAttribute("rx")) - ry = float(n.getAttribute("ry")) - self.out.write("%g 0 0 %g %g %g e\n" % (rx, ry, cx, cy)) - self.out.write('\n') - - def node_line(self, n): - self.out.write('\n') - x1 = 0; y1 = 0; x2 = 0; y2 = 0 - if n.hasAttribute("x1"): - x1 = float(n.getAttribute("x1")) - if n.hasAttribute("y1"): - y1 = float(n.getAttribute("y1")) - if n.hasAttribute("x2"): - x2 = float(n.getAttribute("x2")) - if n.hasAttribute("y2"): - y2 = float(n.getAttribute("y2")) - self.out.write("%g %g m %g %g l\n" % (x1, y1, x2, y2)) - self.out.write('\n') - - def node_polyline(self, n): - self.polygon(n, closed=False) - - def node_polygon(self, n): - self.polygon(n, closed=True) - - def polygon(self, n, closed): - self.out.write('\n') - d = parse_list(n.getAttribute("points")) - op = "m" - while d: - x = float(d.pop(0)) - y = float(d.pop(0)) - self.out.write("%g %g %s\n" % (x, y, op)) - op = "l" - if closed: - self.out.write("h\n") - self.out.write('\n') - - def node_path(self, n): - self.out.write('\n') - d = n.getAttribute("d") - parse_path(self.out, d) - self.out.write('\n') - -# -------------------------------------------------------------------- - -def main(): - if len(sys.argv) != 2 and len(sys.argv) != 3: - sys.stderr.write("Usage: svgtoipe [ ]\n") - return - fname = sys.argv[1] - if len(sys.argv) > 2: - outname = sys.argv[2] - else: - if fname[-4:].lower() == ".svg": - outname = fname[:-4] + ".ipe" - else: - outname = fname + ".ipe" - svg = Svg(fname) - svg.parse_svg(outname) - -if __name__ == '__main__': - main() - -# --------------------------------------------------------------------