summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2014-11-23 20:58:57 +0000
committerJohan B. C. Engelen <j.b.c.engelen@alumnus.utwente.nl>2014-11-23 20:58:57 +0000
commitc93948dfbffd855360c6f97438e001ed6a6c61d0 (patch)
tree1fdc5661c2ffe4c95e0a6b48f19442344e306393
parenti18n. Fix for Bug #1388916 (There seem to be untranslatable strings in MapSym... (diff)
downloadinkscape-c93948dfbffd855360c6f97438e001ed6a6c61d0.tar.gz
inkscape-c93948dfbffd855360c6f97438e001ed6a6c61d0.zip
Extensions: try to calculate the SVG unit
We cannot use inkscape:document-unit for the SVG unit, because it specifies the UI display unit in Inkscape and is unrelated to the units used for SVG values. Instead, the real units of the SVG values is defined by document height/width and the viewbox. The calculation assumes isotropic units (give me a break!) and only looks at the width. It tries to match that with a list of known units. If no match found: assume 'px' units. Finds 'px' units for legacy Inkscape documents without viewbox. (bzr r13750)
-rwxr-xr-xshare/extensions/inkex.py62
1 files changed, 55 insertions, 7 deletions
diff --git a/share/extensions/inkex.py b/share/extensions/inkex.py
index 0f880005d..a564b5c8d 100755
--- a/share/extensions/inkex.py
+++ b/share/extensions/inkex.py
@@ -101,6 +101,13 @@ def errormsg(msg):
else:
sys.stderr.write((unicode(msg, "utf-8", errors='replace') + "\n").encode("UTF-8"))
+def are_near_relative(a, b, eps):
+ if (a-b <= a*eps) and (a-b >= -a*eps):
+ return True
+ else:
+ return False
+
+
# third party library
try:
from lxml import etree
@@ -277,16 +284,57 @@ class Effect:
retval = None
return retval
- def getDocumentUnit(self):
- docunit = self.document.xpath('//sodipodi:namedview/@inkscape:document-units', namespaces=NSS)
- if docunit:
- return docunit[0]
- else:
- return 'px'
-
#a dictionary of unit to user unit conversion factors
__uuconv = {'in':96.0, 'pt':1.33333333333, 'px':1.0, 'mm':3.77952755913, 'cm':37.7952755913,
'm':3779.52755913, 'km':3779527.55913, 'pc':16.0, 'yd':3456.0 , 'ft':1152.0}
+
+ # Function returns the unit used for the values in SVG.
+ # For lack of an attribute in SVG that explicitly defines what units are used for SVG coordinates,
+ # try to calculate the unit from the SVG width and SVG viewbox.
+ # Defaults to 'px' units.
+ def getDocumentUnit(self):
+ svgunit = 'px' #default to pixels
+
+ svgwidth = self.document.getroot().get('width')
+ viewboxstr = self.document.getroot().get('viewBox')
+ if viewboxstr:
+ unitmatch = re.compile('(%s)$' % '|'.join(self.__uuconv.keys()))
+ param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)')
+
+ p = param.match(svgwidth)
+ u = unitmatch.search(svgwidth)
+
+ width = 100 #default
+ viewboxwidth = 100 #default
+ svgwidthunit = 'px' #default assume 'px' unit
+ if p:
+ width = float(p.string[p.start():p.end()])
+ else:
+ errormsg(_("SVG Width not set correctly! Assuming width = 100"))
+ if u:
+ svgwidthunit = u.string[u.start():u.end()]
+
+ viewboxnumbers = []
+ for t in viewboxstr.split():
+ try:
+ viewboxnumbers.append(float(t))
+ except ValueError:
+ pass
+ if len(viewboxnumbers) == 4: #check for correct number of numbers
+ viewboxwidth = viewboxnumbers[2] - viewboxnumbers[0]
+
+ svgunitfactor = self.__uuconv[svgwidthunit] * width / viewboxwidth
+
+ # try to find the svgunitfactor in the list of units known. If we don't find something, ...
+ eps = 0.01 #allow 1% error in factor
+ for key in self.__uuconv:
+ if are_near_relative(self.__uuconv[key], svgunitfactor, eps):
+ #found match!
+ svgunit = key;
+
+ return svgunit
+
+
def unittouu(self, string):
'''Returns userunits given a string representation of units in another system'''
unit = re.compile('(%s)$' % '|'.join(self.__uuconv.keys()))