22class_name ElementPath extends Element
33
44const name = "path"
5- const possible_conversions : PackedStringArray = []
5+ const possible_conversions : PackedStringArray = ["polygon" , "polyline" ]
66
77func user_setup (precise_position := PackedFloat64Array ([0.0 , 0.0 ])) -> void :
88 if precise_position != PackedFloat64Array ([0.0 , 0.0 ]):
@@ -158,7 +158,6 @@ func get_bounding_box() -> Rect2:
158158
159159 return Rect2 (min_x , min_y , max_x - min_x , max_y - min_y )
160160
161-
162161func _solve_quadratic (a : float , b : float , c : float ) -> Array [float ]:
163162 if a == 0 :
164163 return [- c / b ]
@@ -168,3 +167,64 @@ func _solve_quadratic(a: float, b: float, c: float) -> Array[float]:
168167 return []
169168 else :
170169 return [(- b + D ) / (2 * a ), (- b - D ) / (2 * a )]
170+
171+
172+ func can_replace (new_element : String ) -> bool :
173+ var pathdata : AttributePathdata = get_attribute ("d" )
174+ var command_count := pathdata .get_command_count ()
175+
176+ match new_element :
177+ "polygon" :
178+ if command_count == 0 :
179+ return true
180+ if not pathdata .get_command (0 ) is PathCommand .MoveCommand :
181+ return false
182+
183+ for i in range (1 , command_count - 1 ):
184+ if not pathdata .is_conversion_exact (i , AttributePathdata .Conversion .ANY_TO_LINE , true ):
185+ return false
186+ if command_count >= 2 and not pathdata .get_command (command_count - 1 ) is PathCommand .CloseCommand :
187+ return false
188+ return true
189+ "polyline" :
190+ if command_count == 0 :
191+ return true
192+ if not pathdata .get_command (0 ) is PathCommand .MoveCommand :
193+ return false
194+
195+ for i in range (1 , command_count ):
196+ if not pathdata .is_conversion_exact (i , AttributePathdata .Conversion .ANY_TO_LINE , true ):
197+ return false
198+ return true
199+ return false
200+
201+ func get_replacement (new_element : String ) -> Element :
202+ if not can_replace (new_element ):
203+ return null
204+
205+ var element := DB .element (new_element )
206+ var pathdata : AttributePathdata = get_attribute ("d" )
207+ var command_count := pathdata .get_command_count ()
208+ var dropped_attributes : PackedStringArray
209+ match new_element :
210+ "polygon" :
211+ dropped_attributes = PackedStringArray (["points" , "d" ])
212+ var points := PackedFloat64Array ()
213+ # Skip the closure if there are multiple points.
214+ for i in (command_count if command_count < 2 else command_count - 1 ):
215+ var command := pathdata .get_command (i )
216+ var x : float = command .x if not command is PathCommand .VerticalLineCommand else command .start_x
217+ var y : float = command .y if not command is PathCommand .HorizontalLineCommand else command .start_y
218+ points .append_array (PackedFloat64Array ([x , y ]))
219+ element .set_attribute ("points" , points )
220+ "polyline" :
221+ dropped_attributes = PackedStringArray (["points" , "d" ])
222+ var points := PackedFloat64Array ()
223+ for i in command_count :
224+ var command := pathdata .get_command (i )
225+ var x : float = command .x if not command is PathCommand .VerticalLineCommand else command .start_x
226+ var y : float = command .y if not command is PathCommand .HorizontalLineCommand else command .start_y
227+ points .append_array (PackedFloat64Array ([x , y ]))
228+ element .set_attribute ("points" , points )
229+ apply_to (element , dropped_attributes )
230+ return element
0 commit comments