|
|
|
@ -1,20 +1,32 @@ |
|
|
|
|
# svgfig.py copyright (C) 2008 Jim Pivarski <jpivarski@gmail.com> |
|
|
|
|
# |
|
|
|
|
# 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 2 |
|
|
|
|
# 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, write to the Free Software |
|
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
|
|
|
# |
|
|
|
|
# Full licence is in the file COPYING and at http://www.gnu.org/copyleft/gpl.html |
|
|
|
|
# BSD 3-Clause License |
|
|
|
|
|
|
|
|
|
# Copyright (c) 2022, Jim Pivarski |
|
|
|
|
# All rights reserved. |
|
|
|
|
|
|
|
|
|
# Redistribution and use in source and binary forms, with or without |
|
|
|
|
# modification, are permitted provided that the following conditions are met: |
|
|
|
|
|
|
|
|
|
# 1. Redistributions of source code must retain the above copyright notice, this |
|
|
|
|
# list of conditions and the following disclaimer. |
|
|
|
|
|
|
|
|
|
# 2. Redistributions in binary form must reproduce the above copyright notice, |
|
|
|
|
# this list of conditions and the following disclaimer in the documentation |
|
|
|
|
# and/or other materials provided with the distribution. |
|
|
|
|
|
|
|
|
|
# 3. Neither the name of the copyright holder nor the names of its |
|
|
|
|
# contributors may be used to endorse or promote products derived from |
|
|
|
|
# this software without specific prior written permission. |
|
|
|
|
|
|
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
|
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
|
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
|
|
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
|
|
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
|
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
|
|
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
|
|
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|
|
|
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
|
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
|
|
|
|
|
|
import re, codecs, os, platform, copy, itertools, math, cmath, random, sys, copy |
|
|
|
|
_epsilon = 1e-5 |
|
|
|
@ -29,16 +41,24 @@ try: |
|
|
|
|
except NameError: |
|
|
|
|
unicode = lambda s: str(s) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
xrange # Python 2 |
|
|
|
|
except NameError: |
|
|
|
|
xrange = range # Python 3 |
|
|
|
|
if re.search("windows", platform.system(), re.I): |
|
|
|
|
try: |
|
|
|
|
import _winreg |
|
|
|
|
_default_directory = _winreg.QueryValueEx(_winreg.OpenKey(_winreg.HKEY_CURRENT_USER, |
|
|
|
|
r"Software\Microsoft\Windows\Current Version\Explorer\Shell Folders"), "Desktop")[0] |
|
|
|
|
# tmpdir = _winreg.QueryValueEx(_winreg.OpenKey(_winreg.HKEY_CURRENT_USER, "Environment"), "TEMP")[0] |
|
|
|
|
# if tmpdir[0:13] != "%USERPROFILE%": |
|
|
|
|
# tmpdir = os.path.expanduser("~") + tmpdir[13:] |
|
|
|
|
except: |
|
|
|
|
_default_directory = os.path.expanduser("~") + os.sep + "Desktop" |
|
|
|
|
|
|
|
|
|
_default_fileName = "tmp.svg" |
|
|
|
|
|
|
|
|
|
_hacks = {} |
|
|
|
|
_hacks["inkscape-text-vertical-shift"] = False |
|
|
|
|
|
|
|
|
|
__version__ = "1.0.1" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def rgb(r, g, b, maximum=1.): |
|
|
|
|
"""Create an SVG color string "#xxyyzz" from r, g, and b. |
|
|
|
@ -437,9 +457,12 @@ class SVG: |
|
|
|
|
|
|
|
|
|
return output |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def interpret_fileName(fileName=None): |
|
|
|
|
return fileName or _default_fileName |
|
|
|
|
def interpret_fileName(self, fileName=None): |
|
|
|
|
if fileName is None: |
|
|
|
|
fileName = _default_fileName |
|
|
|
|
if re.search("windows", platform.system(), re.I) and not os.path.isabs(fileName): |
|
|
|
|
fileName = _default_directory + os.sep + fileName |
|
|
|
|
return fileName |
|
|
|
|
|
|
|
|
|
def save(self, fileName=None, encoding="utf-8", compresslevel=None): |
|
|
|
|
"""Save to a file for viewing. Note that svg.save() overwrites the file named _default_fileName. |
|
|
|
@ -591,7 +614,7 @@ def template(fileName, svg, replaceme="REPLACEME"): |
|
|
|
|
|
|
|
|
|
def load(fileName): |
|
|
|
|
"""Loads an SVG image from a file.""" |
|
|
|
|
return load_stream(open(fileName)) |
|
|
|
|
return load_stream(file(fileName)) |
|
|
|
|
|
|
|
|
|
def load_stream(stream): |
|
|
|
|
"""Loads an SVG image from a stream (can be a string or a file object).""" |
|
|
|
@ -1848,7 +1871,7 @@ class Poly: |
|
|
|
|
piecewise-linear segments joining the (x,y) points |
|
|
|
|
"bezier"/"B" d=[(x, y, c1x, c1y, c2x, c2y), ...] |
|
|
|
|
Bezier curve with two control points (control points |
|
|
|
|
precede (x,y), as in SVG paths). If (c1x,c1y) and |
|
|
|
|
preceed (x,y), as in SVG paths). If (c1x,c1y) and |
|
|
|
|
(c2x,c2y) both equal (x,y), you get a linear |
|
|
|
|
interpolation ("lines") |
|
|
|
|
"velocity"/"V" d=[(x, y, vx, vy), ...] |
|
|
|
|