@@ -27,7 +27,7 @@ def path2pathd(path):
2727 return path .get ('d' , '' )
2828
2929
30- def ellipse2pathd (ellipse ):
30+ def ellipse2pathd (ellipse , use_cubics = False ):
3131 """converts the parameters from an ellipse or a circle to a string for a
3232 Path object d-attribute"""
3333
@@ -46,10 +46,32 @@ def ellipse2pathd(ellipse):
4646 cx = float (cx )
4747 cy = float (cy )
4848
49- d = ''
50- d += 'M' + str (cx - rx ) + ',' + str (cy )
51- d += 'a' + str (rx ) + ',' + str (ry ) + ' 0 1,0 ' + str (2 * rx ) + ',0'
52- d += 'a' + str (rx ) + ',' + str (ry ) + ' 0 1,0 ' + str (- 2 * rx ) + ',0'
49+ if use_cubics :
50+ # Modified by NXP 2024, 2025
51+ PATH_KAPPA = 0.552284
52+ rxKappa = rx * PATH_KAPPA ;
53+ ryKappa = ry * PATH_KAPPA ;
54+
55+ #According to the SVG specification (https://lists.w3.org/Archives/Public/www-archive/2005May/att-0005/SVGT12_Main.pdf),
56+ #Section 9.4, "The 'ellipse' element": "The arc of an 'ellipse' element begins at the "3 o'clock" point on
57+ #the radius and progresses towards the "9 o'clock". Therefore, the ellipse begins at the rightmost point
58+ #and progresses clockwise.
59+ d = ''
60+ # Move to the rightmost point
61+ d += 'M' + str (cx + rx ) + ' ' + str (cy )
62+ # Draw bottom-right quadrant
63+ d += 'C' + str (cx + rx ) + ' ' + str (cy + ryKappa ) + ' ' + str (cx + rxKappa ) + ' ' + str (cy + ry ) + ' ' + str (cx ) + ' ' + str (cy + ry )
64+ # Draw bottom-left quadrant
65+ d += 'C' + str (cx - rxKappa ) + ' ' + str (cy + ry ) + ' ' + str (cx - rx ) + ' ' + str (cy + ryKappa ) + ' ' + str (cx - rx ) + ' ' + str (cy )
66+ # Draw top-left quadrant
67+ d += 'C' + str (cx - rx ) + ' ' + str (cy - ryKappa ) + ' ' + str (cx - rxKappa ) + ' ' + str (cy - ry ) + ' ' + str (cx ) + ' ' + str (cy - ry )
68+ # Draw top-right quadrant
69+ d += 'C' + str (cx + rxKappa ) + ' ' + str (cy - ry ) + ' ' + str (cx + rx ) + ' ' + str (cy - ryKappa ) + ' ' + str (cx + rx ) + ' ' + str (cy )
70+ else :
71+ d = ''
72+ d += 'M' + str (cx - rx ) + ',' + str (cy )
73+ d += 'a' + str (rx ) + ',' + str (ry ) + ' 0 1,0 ' + str (2 * rx ) + ',0'
74+ d += 'a' + str (rx ) + ',' + str (ry ) + ' 0 1,0 ' + str (- 2 * rx ) + ',0'
5375
5476 return d + 'z'
5577
@@ -62,6 +84,9 @@ def polyline2pathd(polyline, is_polygon=False):
6284 else :
6385 points = COORD_PAIR_TMPLT .findall (polyline .get ('points' , '' ))
6486
87+ if len (points ) == 0 :
88+ return ''
89+
6590 closed = (float (points [0 ][0 ]) == float (points [- 1 ][0 ]) and
6691 float (points [0 ][1 ]) == float (points [- 1 ][1 ]))
6792
@@ -77,13 +102,13 @@ def polyline2pathd(polyline, is_polygon=False):
77102 return d
78103
79104
80- def polygon2pathd (polyline ):
105+ def polygon2pathd (polyline , is_polygon = True ):
81106 """converts the string from a polygon points-attribute to a string
82107 for a Path object d-attribute.
83108 Note: For a polygon made from n points, the resulting path will be
84109 composed of n lines (even if some of these lines have length zero).
85110 """
86- return polyline2pathd (polyline , True )
111+ return polyline2pathd (polyline , is_polygon )
87112
88113
89114def rect2pathd (rect ):
@@ -205,7 +230,7 @@ def dom2dict(element):
205230 # path strings, add to list
206231 if convert_polygons_to_paths :
207232 pgons = [dom2dict (el ) for el in doc .getElementsByTagName ('polygon' )]
208- d_strings += [polygon2pathd (pg ) for pg in pgons ]
233+ d_strings += [polygon2pathd (pg , True ) for pg in pgons ]
209234 attribute_dictionary_list += pgons
210235
211236 if convert_lines_to_paths :
0 commit comments