From de3629eb969ba6db6aba2f2f8e93c5529615a450 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 13 Jun 2016 18:55:41 +0200 Subject: [PATCH] Add new file rebased away during cleanup of previous patchset --- boxes/svgutil.py | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100755 boxes/svgutil.py diff --git a/boxes/svgutil.py b/boxes/svgutil.py new file mode 100755 index 0000000..c628f87 --- /dev/null +++ b/boxes/svgutil.py @@ -0,0 +1,91 @@ +#!/usr/bin/python3 +# Copyright (C) 2016 Florian Festi +# +# This program 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. +# +# This program 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 this program. If not, see . + +import xml.parsers.expat +import re + +class SVGFile(object): + + pathre = re.compile(r"[MCL]? *((-?\d+\.\d+) (-?\d+\.\d+) *)+") + transformre = re.compile(r"matrix\(" + ",".join([r"(-?\d+(\.\d+)?)"] * 6) + "\)") + + def __init__(self, filename): + self.filename = filename + self.minx = self.maxx = self.miny = self.maxy = None + + def handleStartElement(self, name, attrs): + self.tags.append(name) + if name == "path" and "symbol" not in self.tags: + minx = maxx = miny = maxy = None + m = self.transformre.match(attrs.get("transform", "")) + if m: + matrix = [float(m.group(i)) for i in range(1, 12, 2)] + else: + matrix = [1,0,0, + 0,1,0] + for m in self.pathre.findall(attrs.get("d", "")): + x = float(m[1]) + y = float(m[2]) + tx = matrix[0]*x+matrix[2]*y+matrix[4] + ty = matrix[1]*x+matrix[3]*y+matrix[5] + + if self.minx is None or self.minx > tx: + self.minx = tx + if self.maxx is None or self.maxx < tx: + self.maxx = tx + if self.miny is None or self.miny > ty: + self.miny = ty + if self.maxy is None or self.maxy < ty: + self.maxy = ty + + def handleEndElement(self, name): + last = self.tags.pop() + if last != name: + raise ValueError("Got expected " % (name, last)) + + def getEnvelope(self): + self.tags = [] + p = xml.parsers.expat.ParserCreate() + p.StartElementHandler = self.handleStartElement + p.EndElementHandler = self.handleEndElement + p.ParseFile(open(self.filename, "rb")) + + def rewriteViewPort(self): + f = open(self.filename, "r+") + s = f.read(1024) + + m = re.search(r"""]*width="(\d+pt)" height="(\d+pt)" viewBox="0 (0 (\d+) (\d+))" version="1.1">""", s) + + minx = 10*int(self.minx//10)-10 + maxx = 10*int(self.maxx//10)+10 + miny = 10*int(self.miny//10)-10 + maxy = 10*int(self.maxy//10)+10 + + if m: + f.seek(m.start(1)) + f.write("%4imm" % (maxx-minx)) + f.seek(m.start(2)) + f.write("%4imm" % (maxy-miny)) + f.seek(m.start(3)) + f.write("%3i %3i %3i" % (miny, maxx, maxy-miny)) + else: + raiseValueError("Could not understand SVG file") + + +if __name__ == "__main__": + svg = SVGFile("examples/box.svg") + svg.getEnvelope() + svg.rewriteViewPort()