6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 /* functions used to remove vias, pins ...
57 #ifdef HAVE_LIBDMALLOC
64 /* ---------------------------------------------------------------------------
65 * some local prototypes
67 static void *DestroyVia (PinTypePtr
);
68 static void *DestroyRat (RatTypePtr
);
69 static void *DestroyLine (LayerTypePtr
, LineTypePtr
);
70 static void *DestroyArc (LayerTypePtr
, ArcTypePtr
);
71 static void *DestroyText (LayerTypePtr
, TextTypePtr
);
72 static void *DestroyPolygon (LayerTypePtr
, PolygonTypePtr
);
73 static void *DestroyElement (ElementTypePtr
);
74 static void *RemoveVia (PinTypePtr
);
75 static void *RemoveRat (RatTypePtr
);
76 static void *DestroyPolygonPoint (LayerTypePtr
, PolygonTypePtr
, PointTypePtr
);
77 static void *RemovePolygonContour (LayerTypePtr
, PolygonTypePtr
, Cardinal
);
78 static void *RemovePolygonPoint (LayerTypePtr
, PolygonTypePtr
, PointTypePtr
);
79 static void *RemoveLinePoint (LayerTypePtr
, LineTypePtr
, PointTypePtr
);
81 /* ---------------------------------------------------------------------------
84 static ObjectFunctionType RemoveFunctions
= {
98 static ObjectFunctionType DestroyFunctions
= {
112 static DataTypePtr DestroyTarget
;
113 static bool Bulk
= false;
115 /* ---------------------------------------------------------------------------
119 RemovePCB (PCBTypePtr Ptr
)
121 ClearUndoList (true);
126 /* ---------------------------------------------------------------------------
130 DestroyVia (PinTypePtr Via
)
132 r_delete_entry (DestroyTarget
->via_tree
, (BoxTypePtr
) Via
);
134 if (Via
!= &DestroyTarget
->Via
[--DestroyTarget
->ViaN
])
136 *Via
= DestroyTarget
->Via
[DestroyTarget
->ViaN
];
137 r_substitute (DestroyTarget
->via_tree
, (BoxTypePtr
)
138 (BoxType
*) & DestroyTarget
->Via
[DestroyTarget
->ViaN
],
141 memset (&DestroyTarget
->Via
[DestroyTarget
->ViaN
], 0, sizeof (PinType
));
145 /* ---------------------------------------------------------------------------
146 * destroys a line from a layer
149 DestroyLine (LayerTypePtr Layer
, LineTypePtr Line
)
151 r_delete_entry (Layer
->line_tree
, (BoxTypePtr
) Line
);
152 MYFREE (Line
->Number
);
153 if (Line
!= &Layer
->Line
[--Layer
->LineN
])
155 *Line
= Layer
->Line
[Layer
->LineN
];
156 /* tricky - line pointers are moved around */
157 r_substitute (Layer
->line_tree
, (BoxType
*) & Layer
->Line
[Layer
->LineN
],
160 memset (&Layer
->Line
[Layer
->LineN
], 0, sizeof (LineType
));
164 /* ---------------------------------------------------------------------------
165 * destroys an arc from a layer
168 DestroyArc (LayerTypePtr Layer
, ArcTypePtr Arc
)
170 r_delete_entry (Layer
->arc_tree
, (BoxTypePtr
) Arc
);
171 if (Arc
!= &Layer
->Arc
[--Layer
->ArcN
])
173 *Arc
= Layer
->Arc
[Layer
->ArcN
];
174 r_substitute (Layer
->arc_tree
, (BoxType
*) & Layer
->Arc
[Layer
->ArcN
],
177 memset (&Layer
->Arc
[Layer
->ArcN
], 0, sizeof (ArcType
));
181 /* ---------------------------------------------------------------------------
182 * destroys a polygon from a layer
185 DestroyPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
187 r_delete_entry (Layer
->polygon_tree
, (BoxTypePtr
) Polygon
);
188 FreePolygonMemory (Polygon
);
189 if (Polygon
!= &Layer
->Polygon
[--Layer
->PolygonN
])
191 *Polygon
= Layer
->Polygon
[Layer
->PolygonN
];
192 r_substitute (Layer
->polygon_tree
,
193 (BoxType
*) & Layer
->Polygon
[Layer
->PolygonN
],
194 (BoxType
*) Polygon
);
196 memset (&Layer
->Polygon
[Layer
->PolygonN
], 0, sizeof (PolygonType
));
200 /* ---------------------------------------------------------------------------
201 * removes a polygon-point from a polygon and destroys the data
204 DestroyPolygonPoint (LayerTypePtr Layer
,
205 PolygonTypePtr Polygon
, PointTypePtr Point
)
210 Cardinal contour_start
, contour_end
, contour_points
;
212 point_idx
= polygon_point_idx (Polygon
, Point
);
213 contour
= polygon_point_contour (Polygon
, point_idx
);
214 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
215 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
216 Polygon
->HoleIndex
[contour
];
217 contour_points
= contour_end
- contour_start
;
219 if (contour_points
<= 3)
220 return RemovePolygonContour (Layer
, Polygon
, contour
);
222 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
224 /* remove point from list, keep point order */
225 for (i
= point_idx
; i
< Polygon
->PointN
- 1; i
++)
226 Polygon
->Points
[i
] = Polygon
->Points
[i
+ 1];
229 /* Shift down indices of any holes */
230 for (i
= 0; i
< Polygon
->HoleIndexN
; i
++)
231 if (Polygon
->HoleIndex
[i
] > point_idx
)
232 Polygon
->HoleIndex
[i
]--;
234 SetPolygonBoundingBox (Polygon
);
235 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
236 InitClip (PCB
->Data
, Layer
, Polygon
);
240 /* ---------------------------------------------------------------------------
241 * destroys a text from a layer
244 DestroyText (LayerTypePtr Layer
, TextTypePtr Text
)
246 MYFREE (Text
->TextString
);
247 r_delete_entry (Layer
->text_tree
, (BoxTypePtr
) Text
);
248 if (Text
!= &Layer
->Text
[--Layer
->TextN
])
250 *Text
= Layer
->Text
[Layer
->TextN
];
251 r_substitute (Layer
->text_tree
, (BoxType
*) & Layer
->Text
[Layer
->TextN
],
254 memset (&Layer
->Text
[Layer
->TextN
], 0, sizeof (TextType
));
258 /* ---------------------------------------------------------------------------
262 DestroyElement (ElementTypePtr Element
)
264 if (DestroyTarget
->element_tree
)
265 r_delete_entry (DestroyTarget
->element_tree
, (BoxType
*) Element
);
266 if (DestroyTarget
->pin_tree
)
270 r_delete_entry (DestroyTarget
->pin_tree
, (BoxType
*) pin
);
274 if (DestroyTarget
->pad_tree
)
278 r_delete_entry (DestroyTarget
->pad_tree
, (BoxType
*) pad
);
282 ELEMENTTEXT_LOOP (Element
);
284 if (DestroyTarget
->name_tree
[n
])
285 r_delete_entry (DestroyTarget
->name_tree
[n
], (BoxType
*) text
);
288 FreeElementMemory (Element
);
289 if (Element
!= &DestroyTarget
->Element
[--DestroyTarget
->ElementN
])
291 *Element
= DestroyTarget
->Element
[DestroyTarget
->ElementN
];
292 /* deal with changed element pointer */
293 r_substitute (DestroyTarget
->element_tree
,
294 (BoxType
*) & DestroyTarget
->Element
[DestroyTarget
->
296 (BoxType
*) Element
);
300 pin
->Element
= Element
;
305 pad
->Element
= Element
;
308 ELEMENTTEXT_LOOP (Element
);
310 r_substitute (DestroyTarget
->name_tree
[n
],
311 (BoxType
*) & DestroyTarget
->Element
[DestroyTarget
->
314 text
->Element
= Element
;
317 memset (&DestroyTarget
->Element
[DestroyTarget
->ElementN
], 0,
318 sizeof (ElementType
));
322 /* ---------------------------------------------------------------------------
326 DestroyRat (RatTypePtr Rat
)
328 if (DestroyTarget
->rat_tree
)
329 r_delete_entry (DestroyTarget
->rat_tree
, &Rat
->BoundingBox
);
330 if (Rat
!= &DestroyTarget
->Rat
[--DestroyTarget
->RatN
])
332 *Rat
= DestroyTarget
->Rat
[DestroyTarget
->RatN
];
333 r_substitute (DestroyTarget
->rat_tree
,
334 &DestroyTarget
->Rat
[DestroyTarget
->RatN
].BoundingBox
,
337 memset (&DestroyTarget
->Rat
[DestroyTarget
->RatN
], 0, sizeof (RatType
));
342 /* ---------------------------------------------------------------------------
346 RemoveVia (PinTypePtr Via
)
348 /* erase from screen and memory */
355 MoveObjectToRemoveUndoList (VIA_TYPE
, Via
, Via
, Via
);
359 /* ---------------------------------------------------------------------------
363 RemoveRat (RatTypePtr Rat
)
365 /* erase from screen and memory */
372 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
383 remove_point (const BoxType
* b
, void *cl
)
385 LineType
*line
= (LineType
*) b
;
386 struct rlp_info
*info
= (struct rlp_info
*) cl
;
387 if (line
== info
->line
)
389 if ((line
->Point1
.X
== info
->point
->X
)
390 && (line
->Point1
.Y
== info
->point
->Y
))
393 info
->point
= &line
->Point1
;
394 longjmp (info
->env
, 1);
397 if ((line
->Point2
.X
== info
->point
->X
)
398 && (line
->Point2
.Y
== info
->point
->Y
))
401 info
->point
= &line
->Point2
;
402 longjmp (info
->env
, 1);
407 /* ---------------------------------------------------------------------------
408 * removes a line point, or a line if the selected point is the end
411 RemoveLinePoint (LayerTypePtr Layer
, LineTypePtr Line
, PointTypePtr Point
)
414 struct rlp_info info
;
415 if (&Line
->Point1
== Point
)
416 other
= Line
->Point2
;
418 other
= Line
->Point1
;
421 if (setjmp (info
.env
) == 0)
423 r_search (Layer
->line_tree
, (const BoxType
*) Point
, NULL
, remove_point
,
425 return RemoveLine (Layer
, Line
);
427 MoveObject (LINEPOINT_TYPE
, Layer
, info
.line
, info
.point
,
428 other
.X
- Point
->X
, other
.Y
- Point
->Y
);
429 return (RemoveLine (Layer
, Line
));
432 /* ---------------------------------------------------------------------------
433 * removes a line from a layer
436 RemoveLine (LayerTypePtr Layer
, LineTypePtr Line
)
438 /* erase from screen */
445 MoveObjectToRemoveUndoList (LINE_TYPE
, Layer
, Line
, Line
);
449 /* ---------------------------------------------------------------------------
450 * removes an arc from a layer
453 RemoveArc (LayerTypePtr Layer
, ArcTypePtr Arc
)
455 /* erase from screen */
462 MoveObjectToRemoveUndoList (ARC_TYPE
, Layer
, Arc
, Arc
);
466 /* ---------------------------------------------------------------------------
467 * removes a text from a layer
470 RemoveText (LayerTypePtr Layer
, TextTypePtr Text
)
472 /* erase from screen */
475 EraseText (Layer
, Text
);
479 MoveObjectToRemoveUndoList (TEXT_TYPE
, Layer
, Text
, Text
);
483 /* ---------------------------------------------------------------------------
484 * removes a polygon from a layer
487 RemovePolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
489 /* erase from screen */
492 ErasePolygon (Polygon
);
496 MoveObjectToRemoveUndoList (POLYGON_TYPE
, Layer
, Polygon
, Polygon
);
500 /* ---------------------------------------------------------------------------
501 * removes a contour from a polygon.
502 * If removing the outer contour, it removes the whole polygon.
505 RemovePolygonContour (LayerTypePtr Layer
,
506 PolygonTypePtr Polygon
,
509 Cardinal contour_start
, contour_end
, contour_points
;
513 return RemovePolygon (Layer
, Polygon
);
517 ErasePolygon (Polygon
);
522 /* Copy the polygon to the undo list */
523 AddObjectToRemoveContourUndoList (POLYGON_TYPE
, Layer
, Polygon
);
525 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
526 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
527 Polygon
->HoleIndex
[contour
];
528 contour_points
= contour_end
- contour_start
;
530 /* remove points from list, keep point order */
531 for (i
= contour_start
; i
< Polygon
->PointN
- contour_points
; i
++)
532 Polygon
->Points
[i
] = Polygon
->Points
[i
+ contour_points
];
533 Polygon
->PointN
-= contour_points
;
535 /* remove hole from list and shift down remaining indices */
536 for (i
= contour
; i
< Polygon
->HoleIndexN
; i
++)
537 Polygon
->HoleIndex
[i
- 1] = Polygon
->HoleIndex
[i
] - contour_points
;
538 Polygon
->HoleIndexN
--;
540 InitClip (PCB
->Data
, Layer
, Polygon
);
541 /* redraw polygon if necessary */
544 DrawPolygon (Layer
, Polygon
, 0);
551 /* ---------------------------------------------------------------------------
552 * removes a polygon-point from a polygon
555 RemovePolygonPoint (LayerTypePtr Layer
,
556 PolygonTypePtr Polygon
, PointTypePtr Point
)
561 Cardinal contour_start
, contour_end
, contour_points
;
563 point_idx
= polygon_point_idx (Polygon
, Point
);
564 contour
= polygon_point_contour (Polygon
, point_idx
);
565 contour_start
= (contour
== 0) ? 0 : Polygon
->HoleIndex
[contour
- 1];
566 contour_end
= (contour
== Polygon
->HoleIndexN
) ? Polygon
->PointN
:
567 Polygon
->HoleIndex
[contour
];
568 contour_points
= contour_end
- contour_start
;
570 if (contour_points
<= 3)
571 return RemovePolygonContour (Layer
, Polygon
, contour
);
574 ErasePolygon (Polygon
);
576 /* insert the polygon-point into the undo list */
577 AddObjectToRemovePointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
, point_idx
);
578 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
580 /* remove point from list, keep point order */
581 for (i
= point_idx
; i
< Polygon
->PointN
- 1; i
++)
582 Polygon
->Points
[i
] = Polygon
->Points
[i
+ 1];
585 /* Shift down indices of any holes */
586 for (i
= 0; i
< Polygon
->HoleIndexN
; i
++)
587 if (Polygon
->HoleIndex
[i
] > point_idx
)
588 Polygon
->HoleIndex
[i
]--;
590 SetPolygonBoundingBox (Polygon
);
591 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
592 RemoveExcessPolygonPoints (Layer
, Polygon
);
593 InitClip (PCB
->Data
, Layer
, Polygon
);
595 /* redraw polygon if necessary */
598 DrawPolygon (Layer
, Polygon
, 0);
605 /* ---------------------------------------------------------------------------
609 RemoveElement (ElementTypePtr Element
)
611 /* erase from screen */
612 if ((PCB
->ElementOn
|| PCB
->PinOn
) &&
613 (FRONT (Element
) || PCB
->InvisibleObjectsOn
))
615 EraseElement (Element
);
619 MoveObjectToRemoveUndoList (ELEMENT_TYPE
, Element
, Element
, Element
);
623 /* ----------------------------------------------------------------------
624 * removes all selected and visible objects
625 * returns true if any objects have been removed
628 RemoveSelected (void)
631 if (SelectedOperation (&RemoveFunctions
, false, ALL_TYPES
))
633 IncrementUndoSerialNumber ();
642 /* ---------------------------------------------------------------------------
643 * remove object as referred by pointers and type,
644 * allocated memory is passed to the 'remove undo' list
647 RemoveObject (int Type
, void *Ptr1
, void *Ptr2
, void *Ptr3
)
649 void *ptr
= ObjectOperation (&RemoveFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
653 /* ---------------------------------------------------------------------------
654 * DeleteRats - deletes rat lines only
655 * can delete all rat lines, or only selected one
659 DeleteRats (bool selected
)
661 bool changed
= false;
663 RAT_LOOP (PCB
->Data
);
665 if ((!selected
) || TEST_FLAG (SELECTEDFLAG
, line
))
676 IncrementUndoSerialNumber ();
681 /* ---------------------------------------------------------------------------
682 * remove object as referred by pointers and type
683 * allocated memory is destroyed assumed to already be erased
686 DestroyObject (DataTypePtr Target
, int Type
, void *Ptr1
,
687 void *Ptr2
, void *Ptr3
)
689 DestroyTarget
= Target
;
690 return (ObjectOperation (&DestroyFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
));