List of transformations in transform attribute are now parsed correctly.

pull/20/merge^2
alphanoob1337 2017-04-10 09:19:14 +02:00
parent 3a2cd2c7a0
commit fb49d5b752
3 changed files with 54 additions and 30 deletions

View File

@ -93,35 +93,47 @@ def svg2paths(svg_file_location,
def parse_trafo(trafo_str): def parse_trafo(trafo_str):
"""Returns six matrix elements for a matrix transformation for any valid SVG transformation string.""" """Returns six matrix elements for a matrix transformation for any valid SVG transformation string."""
value_str = trafo_str.split('(')[1].split(')')[0] trafos = trafo_str.split(')')[:-1]
values = list(map(float, value_str.split(','))) trafo_matrix = np.array([1., 0., 0., 0., 1., 0., 0., 0., 1.]).reshape((3, 3)) # Start with neutral matrix
if 'translate' in trafo_str:
x = values[0] for trafo_sub_str in trafos:
y = values[1] if (len(values) > 1) else 0. trafo_sub_str = trafo_sub_str.lstrip(', ')
return [1., 0., 0., 1., x, y] value_str = trafo_sub_str.split('(')[1]
elif 'scale' in trafo_str: values = list(map(float, value_str.split(',')))
x = values[0] if 'translate' in trafo_sub_str:
y = values[1] if (len(values) > 1) else 0. x = values[0]
return [x, 0., 0., y, 0., 0.] y = values[1] if (len(values) > 1) else 0.
elif 'rotate' in trafo_str: trafo_matrix = np.dot(trafo_matrix,
a = values[0]*np.pi/180. np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)))
x = values[1] if (len(values) > 1) else 0. elif 'scale' in trafo_sub_str:
y = values[2] if (len(values) > 2) else 0. x = values[0]
am = np.dot(np.array([np.cos(a), -np.sin(a), 0., np.sin(a), np.cos(a), 0., 0., 0., 1.]).reshape((3, 3)), y = values[1] if (len(values) > 1) else 0.
np.array([1., 0., -x, 0., 1., -y, 0., 0., 1.]).reshape((3, 3))) trafo_matrix = np.dot(trafo_matrix,
am = list(np.dot(np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)), am).reshape((9, ))[:6]) np.array([x, 0., 0., 0., y, 0., 0., 0., 1.]).reshape((3, 3)))
am = am[::3]+am[1::3]+am[2::3] elif 'rotate' in trafo_sub_str:
return am a = values[0]*np.pi/180.
elif 'skewX' in trafo_str: x = values[1] if (len(values) > 1) else 0.
a = values[0]*np.pi/180. y = values[2] if (len(values) > 2) else 0.
return [1., 0., np.tan(a), 1., 0., 0.] am = np.dot(np.array([np.cos(a), -np.sin(a), 0., np.sin(a), np.cos(a), 0., 0., 0., 1.]).reshape((3, 3)),
elif 'skewY' in trafo_str: np.array([1., 0., -x, 0., 1., -y, 0., 0., 1.]).reshape((3, 3)))
a = values[0]*np.pi/180. am = np.dot(np.array([1., 0., x, 0., 1., y, 0., 0., 1.]).reshape((3, 3)), am)
return [1., np.tan(a), 0., 1., 0., 0.] trafo_matrix = np.dot(trafo_matrix, am)
else: elif 'skewX' in trafo_sub_str:
while len(values) < 6: a = values[0]*np.pi/180.
values += [0.] trafo_matrix = np.dot(trafo_matrix,
return values np.array([1., np.tan(a), 0., 0., 1., 0., 0., 0., 1.]).reshape((3, 3)))
elif 'skewY' in trafo_sub_str:
a = values[0]*np.pi/180.
trafo_matrix = np.dot(trafo_matrix,
np.array([1., 0., 0., np.tan(a), 1., 0., 0., 0., 1.]).reshape((3, 3)))
else: # Assume matrix transformation
while len(values) < 6:
values += [0.]
trafo_matrix = np.dot(trafo_matrix,
np.array([values[::2], values[1::2], [0., 0., 1.]]))
trafo_list = list(trafo_matrix.reshape((9,))[:6])
return trafo_list[::3]+trafo_list[1::3]+trafo_list[2::3]
def parse_node(node): def parse_node(node):
"""Recursively iterate over nodes. Parse the groups individually to apply group transformations.""" """Recursively iterate over nodes. Parse the groups individually to apply group transformations."""

View File

@ -1,5 +1,5 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<svg id="rootn" version="1.1" baseProfile="full" width="1100" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg id="rootn" version="1.1" baseProfile="full" width="1250" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
<path <path
id="p0" id="p0"
style="stroke:#ff0000;stroke-width:2." style="stroke:#ff0000;stroke-width:2."
@ -78,4 +78,15 @@
d="m 0.,0. 100.,0." /> d="m 0.,0. 100.,0." />
</g> </g>
</g> </g>
<path
id="p14"
style="stroke:#ff0000;stroke-width:2."
d="m 1100.,100. 100.,0." />
<g id="concatenated" transform="translate(1150.,150.),rotate(-90.)">
<path
id="p15"
style="stroke:#ff0000;stroke-width:2."
d="m 0.,0. 100.,0." />
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -11,4 +11,5 @@ class TestSvg2pathsGroups(TestCase):
self.assertTrue((len(paths) % 2) == 0) self.assertTrue((len(paths) % 2) == 0)
for i in range(len(paths)//2): for i in range(len(paths)//2):
print(i * 2)
self.assertTrue(len(paths[i * 2].intersect(paths[i * 2 + 1])) > 0, 'Path '+str(i * 2)+' does not intersect path '+str(i * 2 + 1)+'!') self.assertTrue(len(paths[i * 2].intersect(paths[i * 2 + 1])) > 0, 'Path '+str(i * 2)+' does not intersect path '+str(i * 2 + 1)+'!')