diff options
| author | Johan B. C. Engelen <jbc.engelen@swissonline.ch> | 2014-11-23 20:58:57 +0000 |
|---|---|---|
| committer | Johan B. C. Engelen <j.b.c.engelen@alumnus.utwente.nl> | 2014-11-23 20:58:57 +0000 |
| commit | c93948dfbffd855360c6f97438e001ed6a6c61d0 (patch) | |
| tree | 1fdc5661c2ffe4c95e0a6b48f19442344e306393 | |
| parent | i18n. Fix for Bug #1388916 (There seem to be untranslatable strings in MapSym... (diff) | |
| download | inkscape-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-x | share/extensions/inkex.py | 62 |
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())) |
