@@ -12,27 +12,27 @@ def to_svg(patch: Patch, ind: Tuple[int, ...]) -> str:
12
12
v , c = patch .vert [ind ], patch .command [ind ]
13
13
if v .shape [0 ] == 0 :
14
14
return "<g></g>"
15
- line = ""
15
+ parts = []
16
16
i = 0
17
17
while i < c .shape [0 ]:
18
18
if c [i ] == chalk .backend .patch .Command .MOVETO .value :
19
- line += f"M { v [i , 0 ]} { v [i , 1 ]} "
19
+ parts . append ( f"M { v [i , 0 ]:.2f } { v [i , 1 ]:.2f } " )
20
20
i += 1
21
21
elif c [i ] == chalk .backend .patch .Command .LINETO .value :
22
- line += f"L { v [i , 0 ]} { v [i , 1 ]} "
22
+ parts . append ( f"L { v [i , 0 ]} { v [i , 1 ]} " )
23
23
i += 1
24
24
elif c [i ] == chalk .backend .patch .Command .CURVE3 .value :
25
- line += f"Q { v [i , 0 ]} { v [i , 1 ]} { v [i + 1 , 0 ]} { v [i + 1 , 1 ]} "
25
+ parts . append ( f"Q { v [i , 0 ]} { v [i , 1 ]} { v [i + 1 , 0 ]} { v [i + 1 , 1 ]} " )
26
26
i += 2
27
27
elif c [i ] == chalk .backend .patch .Command .CLOSEPOLY .value :
28
- line += "Z"
28
+ parts . append ( "Z" )
29
29
i += 1
30
30
elif c [i ] == chalk .backend .patch .Command .SKIP .value :
31
31
i += 1
32
32
elif c [i ] == chalk .backend .patch .Command .CURVE4 .value :
33
- line += f"C { v [i , 0 ]} { v [i , 1 ]} { v [i + 1 , 0 ]} { v [i + 1 , 1 ]} { v [i + 2 , 0 ]} { v [i + 2 , 1 ]} "
33
+ parts . append ( f"C { v [i , 0 ]:.2f } { v [i , 1 ]:.2f } { v [i + 1 , 0 ]:.2f } { v [i + 1 , 1 ]:.2f } { v [i + 2 , 0 ]:.2f } { v [i + 2 , 1 ]:.2f } " )
34
34
i += 3
35
- return line
35
+ return " " . join ( parts )
36
36
37
37
38
38
def write_style (d : Dict [str , Any ]) -> Dict [str , str ]:
@@ -51,48 +51,68 @@ def write_style(d: Dict[str, Any]) -> Dict[str, str]:
51
51
return out
52
52
53
53
54
- def render_svg_patches (patches : List [Patch ], animate :bool = False , time_steps = 0 ) -> str :
55
- out = ""
56
- patches = [chalk .backend .patch .order_patches (patches , (step ,))
57
- for step in range (time_steps )]
58
- for v in zip (* patches ):
59
- out += f"""
60
- <path>
61
- """
62
- lines = []
63
- css = {}
64
- for ind , patch , style_new in v :
65
- lines .append (to_svg (patch , ind ))
66
- s = write_style (style_new )
67
- for k , v in s .items ():
68
- css .setdefault (k , []).append (v )
69
-
70
- values = ";" .join (lines )
71
- out += f"""
72
- <animate attributeName="d" values="{ values } " dur="2s" repeatCount="indefinite"/>
54
+ def render_svg_patches (patches : List [Patch ], animate :bool = False , time_steps :int = 0 ) -> str :
55
+ if animate :
56
+ out = ""
57
+ patches = [chalk .backend .patch .order_patches (patches , (step ,))
58
+ for step in range (time_steps )]
59
+ for v in zip (* patches ):
60
+ out += "\n \n <path>\n "
61
+ lines = []
62
+ css = {}
63
+
64
+
65
+ for ind , patch , style_new in v :
66
+
67
+ lines .append (to_svg (patch , ind ))
68
+ s = write_style (style_new )
69
+ for k , v in s .items ():
70
+ css .setdefault (k , []).append (v )
71
+ s = set (lines )
72
+ if len (s ) == 1 :
73
+ out += f"""
74
+ <set attributeName="d" to="{ list (s )[0 ]} "/>
75
+ """
76
+ else :
77
+ values = ";" .join (lines )
78
+ out += f"""
79
+ <animate attributeName="d" values="{ values } " dur="2s" repeatCount="indefinite"/>
80
+ """
81
+ for k , v in css .items ():
82
+ s = set (v )
83
+ if len (s ) == 1 :
84
+ out += f"""<set attributeName="{ k } " to="{ list (s )[0 ]} "/>"""
85
+
86
+ else :
87
+ out += f"""
88
+ <animate attributeName="{ k } " values="{ ';' .join (v )} " dur="2s" repeatCount="indefinite"/>
73
89
"""
74
- for k , v in css .items ():
90
+ out += "</path>\n \n "
91
+ return out
92
+ else :
93
+ out = ""
94
+ for ind , patch , style_new in chalk .backend .patch .order_patches (patches ):
95
+ inner = to_svg (patch , ind )
96
+ style_t = ";" .join ([f"{ k } :{ v } " for k , v in write_style (style_new ).items ()] )
75
97
out += f"""
76
- <animate attributeName="{ k } " values="{ ';' .join (v )} " dur="2s" repeatCount="indefinite"/>
77
- """
78
- out += """
79
- </path>
80
- """
81
- return out
82
-
98
+ <g style="{ style_t } ">
99
+ <path d="{ inner } " />
100
+ </g>"""
101
+ return out
83
102
def patches_to_file (
84
103
patches : List [Patch ], path : str , height : tx .IntLike ,
85
104
width : tx .IntLike ,
86
105
animate : bool = False ,
87
- time_steps = 0
106
+ time_steps : int = 0
88
107
) -> None :
89
- dwg = f"""<?xml version="1.0" encoding="utf-8" ?>
90
- <svg baseProfile="full" height="{ int (height )} " version="1.1" width="{ int (width )} " xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
91
- """
92
- dwg += render_svg_patches (patches , animate , time_steps )
93
- dwg += "</svg>"
94
108
with open (path , "w" ) as f :
95
- f .write (dwg )
109
+ f .write (f"""<?xml version="1.0" encoding="utf-8" ?>
110
+ <svg baseProfile="full" height="{ int (height )} " version="1.1" width="{ int (width )} " xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
111
+ """ )
112
+
113
+ out = render_svg_patches (patches , animate , time_steps )
114
+ f .write (out )
115
+ f .write ("</svg>" )
96
116
97
117
98
118
def render (
0 commit comments