Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions svgpathtools/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -2741,14 +2741,14 @@ def d(self, useSandT=False, use_closed_attrib=False, rel=False):
_seg_start = seg_start - current_pos if current_pos is not None else seg_start
else:
_seg_start = seg_start
parts.append('M {},{}'.format(_seg_start.real, _seg_start.imag))
parts.append('M {:g},{:g}'.format(_seg_start.real, _seg_start.imag))

if isinstance(segment, Line):
if rel:
_seg_end = segment.end - seg_start
else:
_seg_end = segment.end
parts.append('L {},{}'.format(_seg_end.real, _seg_end.imag))
parts.append('L {:g},{:g}'.format(_seg_end.real, _seg_end.imag))
elif isinstance(segment, CubicBezier):
if useSandT and segment.is_smooth_from(previous_segment,
warning_on=False):
Expand All @@ -2760,7 +2760,7 @@ def d(self, useSandT=False, use_closed_attrib=False, rel=False):
_seg_end = segment.end
args = (_seg_control2.real, _seg_control2.imag,
_seg_end.real, _seg_end.imag)
parts.append('S {},{} {},{}'.format(*args))
parts.append('S {:g},{:g} {:g},{:g}'.format(*args))
else:
if rel:
_seg_control1 = segment.control1 - seg_start
Expand All @@ -2773,7 +2773,7 @@ def d(self, useSandT=False, use_closed_attrib=False, rel=False):
args = (_seg_control1.real, _seg_control1.imag,
_seg_control2.real, _seg_control2.imag,
_seg_end.real, _seg_end.imag)
parts.append('C {},{} {},{} {},{}'.format(*args))
parts.append('C {:g},{:g} {:g},{:g} {:g},{:g}'.format(*args))
elif isinstance(segment, QuadraticBezier):
if useSandT and segment.is_smooth_from(previous_segment,
warning_on=False):
Expand All @@ -2782,7 +2782,7 @@ def d(self, useSandT=False, use_closed_attrib=False, rel=False):
else:
_seg_end = segment.end
args = _seg_end.real, _seg_end.imag
parts.append('T {},{}'.format(*args))
parts.append('T {:g},{:g}'.format(*args))
else:
if rel:
_seg_control = segment.control - seg_start
Expand All @@ -2792,7 +2792,7 @@ def d(self, useSandT=False, use_closed_attrib=False, rel=False):
_seg_end = segment.end
args = (_seg_control.real, _seg_control.imag,
_seg_end.real, _seg_end.imag)
parts.append('Q {},{} {},{}'.format(*args))
parts.append('Q {:g},{:g} {:g},{:g}'.format(*args))

elif isinstance(segment, Arc):
if rel:
Expand All @@ -2802,7 +2802,7 @@ def d(self, useSandT=False, use_closed_attrib=False, rel=False):
args = (segment.radius.real, segment.radius.imag,
segment.rotation,int(segment.large_arc),
int(segment.sweep),_seg_end.real, _seg_end.imag)
parts.append('A {},{} {} {:d},{:d} {},{}'.format(*args))
parts.append('A {:g},{:g} {:g} {:d},{:d} {:g},{:g}'.format(*args))
current_pos = segment.end
previous_segment = segment

Expand Down
35 changes: 20 additions & 15 deletions test/test_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ def test_path_parsing(self):
'M 600,350 L 650,325 A 25,25 -30 0,1 700,300 L 750,275',
]
float_paths = [
'M 100.0,100.0 L 300.0,100.0 L 200.0,300.0 L 100.0,100.0',
'M 0.0,0.0 L 50.0,20.0 M 100.0,100.0 L 300.0,100.0 L 200.0,300.0 L 100.0,100.0',
'M 100.0,100.0 L 200.0,200.0',
'M 100.0,200.0 L 200.0,100.0 L -100.0,-200.0',
'M 100.0,200.0 C 100.0,100.0 250.0,100.0 250.0,200.0 C 250.0,300.0 400.0,300.0 400.0,200.0',
'M 100.0,200.0 C 100.0,100.0 400.0,100.0 400.0,200.0',
'M 100.0,500.0 C 25.0,400.0 475.0,400.0 400.0,500.0',
'M 100.0,800.0 C 175.0,700.0 325.0,700.0 400.0,800.0',
'M 600.0,200.0 C 675.0,100.0 975.0,100.0 900.0,200.0',
'M 600.0,500.0 C 600.0,350.0 900.0,650.0 900.0,500.0',
'M 600.0,800.0 C 625.0,700.0 725.0,700.0 750.0,800.0 C 775.0,900.0 875.0,900.0 900.0,800.0',
'M 200.0,300.0 Q 400.0,50.0 600.0,300.0 Q 800.0,550.0 1000.0,300.0',
'M 100,100 L 300,100 L 200,300 L 100,100',
'M 0,0 L 50,20 M 100,100 L 300,100 L 200,300 L 100,100',
'M 100,100 L 200,200',
'M 100,200 L 200,100 L -100,-200',
'M 100,200 C 100,100 250,100 250,200 C 250,300 400,300 400,200',
'M 100,200 C 100,100 400,100 400,200',
'M 100,500 C 25,400 475,400 400,500',
'M 100,800 C 175,700 325,700 400,800',
'M 600,200 C 675,100 975,100 900,200',
'M 600,500 C 600,350 900,650 900,500',
'M 600,800 C 625,700 725,700 750,800 C 775,900 875,900 900,800',
'M 200,300 Q 400,50 600,300 Q 800,550 1000,300',
'M -3.4e+38,3.4e+38 L -3.4e-38,3.4e-38',
'M 0.0,0.0 L 50.0,20.0 L 200.0,100.0 L 50.0,20.0',
'M 600.0,350.0 L 650.0,325.0 A 27.9508497187,27.9508497187 -30.0 0,1 700.0,300.0 L 750.0,275.0'
Expand All @@ -73,15 +73,20 @@ def test_path_parsing(self):
''.format(path, expected, res))
_assert_d_strings_are_almost_equal(res, expected, self, msg)


def test_normalizing(self):
# Relative paths will be made absolute, subpaths merged if they can,
# and syntax will change.
path = 'M0 0L3.4E2-10L100.0,100M100,100l100,-100'
path = 'M0 0L3.4E2-10L100,100M100,100l100,-100'
ps = 'M 0,0 L 340,-10 L 100,100 L 200,0'
psf = 'M 0.0,0.0 L 340.0,-10.0 L 100.0,100.0 L 200.0,0.0'
psf = 'M 0,0 L 340,-10 L 100,100 L 200,0'
self.assertTrue(parse_path(path).d() in (ps, psf))

def test_floating_point_errors(self):
# Check that reading and then outputting a d-string
# does not introduce floating point error noise.
path = "M 70.63,10.42 C 0.11,0.33 -0.89,2.09 -1.54,2.45 C -4.95,2.73 -17.52,7.24 -39.46,11.04"
self.assertTrue(parse_path(path).d(), path)


if __name__ == '__main__':
unittest.main()
8 changes: 4 additions & 4 deletions test/test_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@ def test_add_group(self):
'base_group', 'new_parent', 'new_child', 'new_leaf']))
self.check_group_count(doc, 7)

path_d = ('M 206.07112,858.41289 L 206.07112,-2.02031 '
'C -50.738,-81.14814 -20.36402,-105.87055 52.52793,-101.01525 '
'L 103.03556,0.0 '
'L 0.0,111.11678')
path_d = ('M 206.071,858.413 L 206.071,-2.02031 '
'C -50.738,-81.1481 -20.364,-105.871 52.5279,-101.015 '
'L 103.036,0 '
'L 0,111.117')

svg_path = doc.add_path(path_d, group=new_leaf)
self.assertEqual(path_d, svg_path.get('d'))
Expand Down
6 changes: 3 additions & 3 deletions test/test_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ def test_pathd_init(self):

def test_issue_99(self):
p = Path("M 100 250 S 200 200 200 250 300 300 300 250")
self.assertEqual(p.d(useSandT=True), 'M 100.0,250.0 S 200.0,200.0 200.0,250.0 S 300.0,300.0 300.0,250.0')
self.assertEqual(p.d(useSandT=True), 'M 100,250 S 200,200 200,250 S 300,300 300,250')
self.assertEqual(p.d(),
'M 100.0,250.0 C 100.0,250.0 200.0,200.0 200.0,250.0 C 200.0,300.0 300.0,300.0 300.0,250.0')
'M 100,250 C 100,250 200,200 200,250 C 200,300 300,300 300,250')
self.assertNotEqual(p.d(),
'M 100.0,250.0 C 100.0,250.0 200.0,200.0 200.0,250.0 C 200.0,250.0 300.0,300.0 300.0,250.0')
'M 100,250 C 100,250 200,200 200,250 C 200,250 300,300 300,250')
6 changes: 4 additions & 2 deletions test/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -1155,8 +1155,8 @@ def scale_a_point(pt, sx, sy=None, origin=0j):

def test_d(self):
# the following two path represent the same path but in absolute and relative forms
abs_s = 'M 38.0,130.0 C 37.0,132.0 38.0,136.0 40.0,137.0 L 85.0,161.0 C 87.0,162.0 91.0,162.0 93.0,160.0 L 127.0,133.0 C 129.0,131.0 129.0,128.0 127.0,126.0 L 80.0,70.0 C 78.0,67.0 75.0,68.0 74.0,70.0 Z'
rel_s = 'm 38.0,130.0 c -1.0,2.0 0.0,6.0 2.0,7.0 l 45.0,24.0 c 2.0,1.0 6.0,1.0 8.0,-1.0 l 34.0,-27.0 c 2.0,-2.0 2.0,-5.0 0.0,-7.0 l -47.0,-56.0 c -2.0,-3.0 -5.0,-2.0 -6.0,0.0 z'
abs_s = 'M 38,130 C 37,132 38,136 40,137 L 85,161 C 87,162 91,162 93,160 L 127,133 C 129,131 129,128 127,126 L 80,70 C 78,67 75,68 74,70 Z'
rel_s = 'm 38,130 c -1,2 0,6 2,7 l 45,24 c 2,1 6,1 8,-1 l 34,-27 c 2,-2 2,-5 0,-7 l -47,-56 c -2,-3 -5,-2 -6,0 z'
path1 = parse_path(abs_s)
path2 = parse_path(rel_s)
self.assertEqual(path1.d(use_closed_attrib=True), abs_s)
Expand All @@ -1165,6 +1165,8 @@ def test_d(self):
self.assertEqual(path2.d(use_closed_attrib=True, rel=True), rel_s)




class Test_ilength(unittest.TestCase):
# See svgpathtools.notes.inv_arclength.py for information on how these
# test values were generated (using the .length() method).
Expand Down
Loading