Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'io_curve_svg/svg_util.py')
-rw-r--r--io_curve_svg/svg_util.py99
1 files changed, 98 insertions, 1 deletions
diff --git a/io_curve_svg/svg_util.py b/io_curve_svg/svg_util.py
index 0aeb2018..42e900b4 100644
--- a/io_curve_svg/svg_util.py
+++ b/io_curve_svg/svg_util.py
@@ -20,6 +20,20 @@
import re
+
+units = {"": 1.0,
+ "px": 1.0,
+ "in": 90.0,
+ "mm": 90.0 / 25.4,
+ "cm": 90.0 / 2.54,
+ "pt": 1.25,
+ "pc": 15.0,
+ "em": 1.0,
+ "ex": 1.0,
+ "INVALID": 1.0, # some DocBook files contain this
+ }
+
+
def srgb_to_linearrgb(c):
if c < 0.04045:
return 0.0 if c < 0.0 else c * (1.0 / 12.92)
@@ -48,6 +62,90 @@ def parse_array_of_floats(text):
return [value_to_float(v[0]) for v in elements]
+def read_float(s: str, i: int = 0):
+ """
+ Reads floating point value from a string. Parsing starts at the given index.
+
+ Returns the value itself (as a string) and index of first character after the value.
+ """
+ start = i
+ n = len(s)
+ token = ''
+
+ # Skip leading whitespace characters
+ while i < n and (s[i].isspace() or s[i] == ','):
+ i += 1
+
+ if i == n:
+ return "0", i
+
+ # Read sign
+ if s[i] == '-':
+ token += '-'
+ i += 1
+ elif s[i] == '+':
+ i += 1
+
+ # Read integer part
+ if s[i].isdigit():
+ while i < n and s[i].isdigit():
+ token += s[i]
+ i += 1
+
+ # Fractional part
+ if i < n and s[i] == '.':
+ token += '.'
+ i += 1
+
+ if i < n and s[i].isdigit():
+ while i < n and s[i].isdigit():
+ token += s[i]
+ i += 1
+ elif i == n or s[i].isspace() or s[i] == ',':
+ # Inkscape sometimes uses weird float format with missed
+ # fractional part after dot. Suppose zero fractional part
+ # for this case
+ pass
+ else:
+ raise Exception('Invalid float value near ' + s[start:start + 10])
+
+ # Degree
+ if i < n and (s[i] == 'e' or s[i] == 'E'):
+ token += s[i]
+ i += 1
+ if s[i] == '+' or s[i] == '-':
+ token += s[i]
+ i += 1
+
+ if s[i].isdigit():
+ while i < n and s[i].isdigit():
+ token += s[i]
+ i += 1
+ else:
+ raise Exception('Invalid float value near ' + s[start:start + 10])
+
+ return token, i
+
+
+def parse_coord(coord, size):
+ """
+ Parse coordinate component to common basis
+
+ Needed to handle coordinates set in cm, mm, inches.
+ """
+
+ token, last_char = read_float(coord)
+ val = float(token)
+ unit = coord[last_char:].strip() # strip() in case there is a space
+
+ if unit == '%':
+ return float(size) / 100.0 * val
+ else:
+ return val * units[unit]
+
+ return val
+
+
def value_to_float(value_encoded: str):
"""
A simple wrapper around float() which supports empty strings (which are converted to 0).
@@ -55,4 +153,3 @@ def value_to_float(value_encoded: str):
if len(value_encoded) == 0:
return 0
return float(value_encoded)
-