4 * \brief Functions used to remove vias, pins ...
8 * <h1><b>Copyright.</b></h1>\n
10 * PCB, interactive printed circuit board design.
12 * Copyright (C) 1994,1995,1996 Thomas Nau
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * Contact addresses for paper mail and Email:
30 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
32 * Thomas.Nau@rz.uni-ulm.de
60 #ifdef HAVE_LIBDMALLOC
64 /* ---------------------------------------------------------------------------
65 * some local prototypes
67 static void *DestroyVia (PinType
*);
68 static void *DestroyRat (RatType
*);
69 static void *DestroyLine (LayerType
*, LineType
*);
70 static void *DestroyArc (LayerType
*, ArcType
*);
71 static void *DestroyText (LayerType
*, TextType
*);
72 static void *DestroyPolygon (LayerType
*, PolygonType
*);
73 static void *DestroyElement (ElementType
*);
74 static void *RemoveVia (PinType
*);
75 static void *RemoveRat (RatType
*);
76 static void *DestroyPolygonPoint (LayerType
*, PolygonType
*, PointType
*);
77 static void *RemovePolygonContour (LayerType
*, PolygonType
*, Cardinal
);
78 static void *RemovePolygonPoint (LayerType
*, PolygonType
*, PointType
*);
79 static void *RemoveLinePoint (LayerType
*, LineType
*, PointType
*);
81 /* ---------------------------------------------------------------------------
84 static ObjectFunctionType RemoveFunctions
= {
98 static ObjectFunctionType DestroyFunctions
= {
112 static DataType
*DestroyTarget
;
113 static bool Bulk
= false;
119 RemovePCB (PCBType
*Ptr
)
121 ClearUndoList (true);
127 * \brief Destroys a via.
130 DestroyVia (PinType
*Via
)
132 r_delete_entry (DestroyTarget
->via_tree
, (BoxType
*) Via
);
135 DestroyTarget
->Via
= g_list_remove (DestroyTarget
->Via
, Via
);
136 DestroyTarget
->ViaN
--;
138 g_slice_free (PinType
, Via
);
144 * \brief Destroys a line from a layer.
147 DestroyLine (LayerType
*Layer
, LineType
*Line
)
149 r_delete_entry (Layer
->line_tree
, (BoxType
*) Line
);
152 Layer
->Line
= g_list_remove (Layer
->Line
, Line
);
155 g_slice_free (LineType
, Line
);
161 * \brief Destroys an arc from a layer.
164 DestroyArc (LayerType
*Layer
, ArcType
*Arc
)
166 r_delete_entry (Layer
->arc_tree
, (BoxType
*) Arc
);
168 Layer
->Arc
= g_list_remove (Layer
->Arc
, Arc
);
171 g_slice_free (ArcType
, Arc
);
177 * \brief Destroys a polygon from a layer.
180 DestroyPolygon (LayerType
*Layer
, PolygonType
*Polygon
)
182 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
183 FreePolygonMemory (Polygon
);
185 Layer
->Polygon
= g_list_remove (Layer
->Polygon
, Polygon
);
188 g_slice_free (PolygonType
, Polygon
);
194 * \brief Removes a polygon-point from a polygon and destroys the data.
197 DestroyPolygonPoint (LayerType
*Layer
,
198 PolygonType
*Polygon
, PointType
*Point
)
203 Cardinal contour_start
, contour_end
, contour_points
;
205 point_idx
= polygon_point_idx (Polygon
, Point
);
206 contour
= polygon_point_contour (Polygon
, point_idx
);
207 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
208 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
209 Polygon
->HoleIndex
[contour
];
210 contour_points
= contour_end
- contour_start
;
212 if (contour_points
<= 3)
213 return RemovePolygonContour (Layer
, Polygon
, contour
);
215 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
217 /* remove point from list, keep point order */
218 for (i
= point_idx
; i
< Polygon
->PointN
- 1; i
++)
219 Polygon
->Points
[i
] = Polygon
->Points
[i
+ 1];
222 /* Shift down indices of any holes */
223 for (i
= 0; i
< Polygon
->HoleIndexN
; i
++)
224 if (Polygon
->HoleIndex
[i
] > point_idx
)
225 Polygon
->HoleIndex
[i
]--;
227 SetPolygonBoundingBox (Polygon
);
228 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
229 InitClip (PCB
->Data
, Layer
, Polygon
);
234 * \brief Destroys a text from a layer.
237 DestroyText (LayerType
*Layer
, TextType
*Text
)
239 free (Text
->TextString
);
240 r_delete_entry (Layer
->text_tree
, (BoxType
*) Text
);
242 Layer
->Text
= g_list_remove (Layer
->Text
, Text
);
245 g_slice_free (TextType
, Text
);
250 /* ---------------------------------------------------------------------------
254 DestroyElement (ElementType
*Element
)
256 if (DestroyTarget
->element_tree
)
257 r_delete_entry (DestroyTarget
->element_tree
, (BoxType
*) Element
);
258 if (DestroyTarget
->pin_tree
)
262 r_delete_entry (DestroyTarget
->pin_tree
, (BoxType
*) pin
);
266 if (DestroyTarget
->pad_tree
)
270 r_delete_entry (DestroyTarget
->pad_tree
, (BoxType
*) pad
);
274 ELEMENTTEXT_LOOP (Element
);
276 if (DestroyTarget
->name_tree
[n
])
277 r_delete_entry (DestroyTarget
->name_tree
[n
], (BoxType
*) text
);
280 FreeElementMemory (Element
);
282 DestroyTarget
->Element
= g_list_remove (DestroyTarget
->Element
, Element
);
283 DestroyTarget
->ElementN
--;
285 g_slice_free (ElementType
, Element
);
291 * \brief Destroys a rat.
294 DestroyRat (RatType
*Rat
)
296 if (DestroyTarget
->rat_tree
)
297 r_delete_entry (DestroyTarget
->rat_tree
, &Rat
->BoundingBox
);
299 DestroyTarget
->Rat
= g_list_remove (DestroyTarget
->Rat
, Rat
);
300 DestroyTarget
->RatN
--;
302 g_slice_free (RatType
, Rat
);
309 * \brief Removes a via.
312 RemoveVia (PinType
*Via
)
314 /* erase from screen and memory */
321 MoveObjectToRemoveUndoList (VIA_TYPE
, Via
, Via
, Via
);
326 * \brief Removes a rat.
329 RemoveRat (RatType
*Rat
)
331 /* erase from screen and memory */
338 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
349 remove_point (const BoxType
* b
, void *cl
)
351 LineType
*line
= (LineType
*) b
;
352 struct rlp_info
*info
= (struct rlp_info
*) cl
;
353 if (line
== info
->line
)
355 if ((line
->Point1
.X
== info
->point
->X
)
356 && (line
->Point1
.Y
== info
->point
->Y
))
359 info
->point
= &line
->Point1
;
360 longjmp (info
->env
, 1);
363 if ((line
->Point2
.X
== info
->point
->X
)
364 && (line
->Point2
.Y
== info
->point
->Y
))
367 info
->point
= &line
->Point2
;
368 longjmp (info
->env
, 1);
374 * \brief Removes a line point, or a line if the selected point is the
378 RemoveLinePoint (LayerType
*Layer
, LineType
*Line
, PointType
*Point
)
381 struct rlp_info info
;
382 if (&Line
->Point1
== Point
)
383 other
= Line
->Point2
;
385 other
= Line
->Point1
;
388 if (setjmp (info
.env
) == 0)
390 r_search (Layer
->line_tree
, (const BoxType
*) Point
, NULL
, remove_point
,
392 return RemoveLine (Layer
, Line
);
394 MoveObject (LINEPOINT_TYPE
, Layer
, info
.line
, info
.point
,
395 other
.X
- Point
->X
, other
.Y
- Point
->Y
);
396 return (RemoveLine (Layer
, Line
));
400 * \brief Removes a line from a layer.
403 RemoveLine (LayerType
*Layer
, LineType
*Line
)
405 /* erase from screen */
412 MoveObjectToRemoveUndoList (LINE_TYPE
, Layer
, Line
, Line
);
417 * \brief Removes an arc from a layer.
420 RemoveArc (LayerType
*Layer
, ArcType
*Arc
)
422 /* erase from screen */
429 MoveObjectToRemoveUndoList (ARC_TYPE
, Layer
, Arc
, Arc
);
434 * \brief Removes a text from a layer.
437 RemoveText (LayerType
*Layer
, TextType
*Text
)
439 /* erase from screen */
442 EraseText (Layer
, Text
);
443 r_delete_entry (Layer
->text_tree
, (BoxType
*) Text
);
447 MoveObjectToRemoveUndoList (TEXT_TYPE
, Layer
, Text
, Text
);
452 * \brief Removes a polygon from a layer.
455 RemovePolygon (LayerType
*Layer
, PolygonType
*Polygon
)
457 /* erase from screen */
460 ErasePolygon (Polygon
);
464 MoveObjectToRemoveUndoList (POLYGON_TYPE
, Layer
, Polygon
, Polygon
);
469 * \brief Removes a contour from a polygon.
471 * If removing the outer contour, it removes the whole polygon.
474 RemovePolygonContour (LayerType
*Layer
,
475 PolygonType
*Polygon
,
478 Cardinal contour_start
, contour_end
, contour_points
;
482 return RemovePolygon (Layer
, Polygon
);
486 ErasePolygon (Polygon
);
491 /* Copy the polygon to the undo list */
492 AddObjectToRemoveContourUndoList (POLYGON_TYPE
, Layer
, Polygon
);
494 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
495 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
496 Polygon
->HoleIndex
[contour
];
497 contour_points
= contour_end
- contour_start
;
499 /* remove points from list, keep point order */
500 for (i
= contour_start
; i
< Polygon
->PointN
- contour_points
; i
++)
501 Polygon
->Points
[i
] = Polygon
->Points
[i
+ contour_points
];
502 Polygon
->PointN
-= contour_points
;
504 /* remove hole from list and shift down remaining indices */
505 for (i
= contour
; i
< Polygon
->HoleIndexN
; i
++)
506 Polygon
->HoleIndex
[i
- 1] = Polygon
->HoleIndex
[i
] - contour_points
;
507 Polygon
->HoleIndexN
--;
509 InitClip (PCB
->Data
, Layer
, Polygon
);
510 /* redraw polygon if necessary */
513 DrawPolygon (Layer
, Polygon
);
521 * \brief Removes a polygon-point from a polygon.
524 RemovePolygonPoint (LayerType
*Layer
,
525 PolygonType
*Polygon
, PointType
*Point
)
530 Cardinal contour_start
, contour_end
, contour_points
;
532 point_idx
= polygon_point_idx (Polygon
, Point
);
533 contour
= polygon_point_contour (Polygon
, point_idx
);
534 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
535 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
536 Polygon
->HoleIndex
[contour
];
537 contour_points
= contour_end
- contour_start
;
539 if (contour_points
<= 3)
540 return RemovePolygonContour (Layer
, Polygon
, contour
);
543 ErasePolygon (Polygon
);
545 /* insert the polygon-point into the undo list */
546 AddObjectToRemovePointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
, point_idx
);
547 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
549 /* remove point from list, keep point order */
550 for (i
= point_idx
; i
< Polygon
->PointN
- 1; i
++)
551 Polygon
->Points
[i
] = Polygon
->Points
[i
+ 1];
554 /* Shift down indices of any holes */
555 for (i
= 0; i
< Polygon
->HoleIndexN
; i
++)
556 if (Polygon
->HoleIndex
[i
] > point_idx
)
557 Polygon
->HoleIndex
[i
]--;
559 SetPolygonBoundingBox (Polygon
);
560 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
561 RemoveExcessPolygonPoints (Layer
, Polygon
);
562 InitClip (PCB
->Data
, Layer
, Polygon
);
564 /* redraw polygon if necessary */
567 DrawPolygon (Layer
, Polygon
);
575 * \brief Removes an element.
578 RemoveElement (ElementType
*Element
)
580 /* erase from screen */
581 if ((PCB
->ElementOn
|| PCB
->PinOn
) &&
582 (FRONT (Element
) || PCB
->InvisibleObjectsOn
))
584 EraseElement (Element
);
588 MoveObjectToRemoveUndoList (ELEMENT_TYPE
, Element
, Element
, Element
);
593 * \brief Removes all selected and visible objects.
595 * \return true if any objects have been removed.
598 RemoveSelected (void)
601 if (SelectedOperation (&RemoveFunctions
, false, ALL_TYPES
))
603 IncrementUndoSerialNumber ();
613 * \brief Remove object as referred by pointers and type,
614 * allocated memory is passed to the 'remove undo' list.
617 RemoveObject (int Type
, void *Ptr1
, void *Ptr2
, void *Ptr3
)
619 void *ptr
= ObjectOperation (&RemoveFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
624 * \brief Deletes rat lines only.
626 * Can delete all rat lines, or only selected one.
629 DeleteRats (bool selected
)
631 bool changed
= false;
633 RAT_LOOP (PCB
->Data
);
635 if ((!selected
) || TEST_FLAG (SELECTEDFLAG
, line
))
646 IncrementUndoSerialNumber ();
652 * \brief Remove object as referred by pointers and type.
654 * Allocated memory is destroyed assumed to already be erased.
657 DestroyObject (DataType
*Target
, int Type
, void *Ptr1
,
658 void *Ptr2
, void *Ptr3
)
660 DestroyTarget
= Target
;
661 return (ObjectOperation (&DestroyFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
));