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 *RemovePolygonPoint (LayerTypePtr
, PolygonTypePtr
, PointTypePtr
);
78 static void *RemoveLinePoint (LayerTypePtr
, LineTypePtr
, PointTypePtr
);
80 /* ---------------------------------------------------------------------------
83 static ObjectFunctionType RemoveFunctions
= {
97 static ObjectFunctionType DestroyFunctions
= {
111 static DataTypePtr DestroyTarget
;
112 static Boolean Bulk
= False
;
114 /* ---------------------------------------------------------------------------
118 RemovePCB (PCBTypePtr Ptr
)
120 ClearUndoList (True
);
125 /* ---------------------------------------------------------------------------
129 DestroyVia (PinTypePtr Via
)
131 r_delete_entry (DestroyTarget
->via_tree
, (BoxTypePtr
) Via
);
133 if (Via
!= &DestroyTarget
->Via
[--DestroyTarget
->ViaN
])
135 *Via
= DestroyTarget
->Via
[DestroyTarget
->ViaN
];
136 r_substitute (DestroyTarget
->via_tree
, (BoxTypePtr
)
137 (BoxType
*) & DestroyTarget
->Via
[DestroyTarget
->ViaN
],
140 memset (&DestroyTarget
->Via
[DestroyTarget
->ViaN
], 0, sizeof (PinType
));
144 /* ---------------------------------------------------------------------------
145 * destroys a line from a layer
148 DestroyLine (LayerTypePtr Layer
, LineTypePtr Line
)
150 r_delete_entry (Layer
->line_tree
, (BoxTypePtr
) Line
);
151 MYFREE (Line
->Number
);
152 if (Line
!= &Layer
->Line
[--Layer
->LineN
])
154 *Line
= Layer
->Line
[Layer
->LineN
];
155 /* tricky - line pointers are moved around */
156 r_substitute (Layer
->line_tree
, (BoxType
*) & Layer
->Line
[Layer
->LineN
],
159 memset (&Layer
->Line
[Layer
->LineN
], 0, sizeof (LineType
));
163 /* ---------------------------------------------------------------------------
164 * destroys an arc from a layer
167 DestroyArc (LayerTypePtr Layer
, ArcTypePtr Arc
)
169 r_delete_entry (Layer
->arc_tree
, (BoxTypePtr
) Arc
);
170 if (Arc
!= &Layer
->Arc
[--Layer
->ArcN
])
172 *Arc
= Layer
->Arc
[Layer
->ArcN
];
173 r_substitute (Layer
->arc_tree
, (BoxType
*) & Layer
->Arc
[Layer
->ArcN
],
176 memset (&Layer
->Arc
[Layer
->ArcN
], 0, sizeof (ArcType
));
180 /* ---------------------------------------------------------------------------
181 * destroys a polygon from a layer
184 DestroyPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
186 r_delete_entry (Layer
->polygon_tree
, (BoxTypePtr
) Polygon
);
187 FreePolygonMemory (Polygon
);
188 if (Polygon
!= &Layer
->Polygon
[--Layer
->PolygonN
])
190 *Polygon
= Layer
->Polygon
[Layer
->PolygonN
];
191 r_substitute (Layer
->polygon_tree
,
192 (BoxType
*) & Layer
->Polygon
[Layer
->PolygonN
],
193 (BoxType
*) Polygon
);
195 memset (&Layer
->Polygon
[Layer
->PolygonN
], 0, sizeof (PolygonType
));
199 /* ---------------------------------------------------------------------------
200 * removes a polygon-point from a polygon and destroys the data
203 DestroyPolygonPoint (LayerTypePtr Layer
,
204 PolygonTypePtr Polygon
, PointTypePtr Point
)
208 if (Polygon
->PointN
<= 3)
209 return RemovePolygon (Layer
, Polygon
);
210 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
211 for (ptr
= Point
+ 1; ptr
!= &Polygon
->Points
[Polygon
->PointN
]; ptr
++)
217 SetPolygonBoundingBox (Polygon
);
218 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
219 InitClip (PCB
->Data
, Layer
, Polygon
);
223 /* ---------------------------------------------------------------------------
224 * destroys a text from a layer
227 DestroyText (LayerTypePtr Layer
, TextTypePtr Text
)
229 MYFREE (Text
->TextString
);
230 r_delete_entry (Layer
->text_tree
, (BoxTypePtr
) Text
);
231 if (Text
!= &Layer
->Text
[--Layer
->TextN
])
233 *Text
= Layer
->Text
[Layer
->TextN
];
234 r_substitute (Layer
->text_tree
, (BoxType
*) & Layer
->Text
[Layer
->TextN
],
237 memset (&Layer
->Text
[Layer
->TextN
], 0, sizeof (TextType
));
241 /* ---------------------------------------------------------------------------
245 DestroyElement (ElementTypePtr Element
)
247 if (DestroyTarget
->element_tree
)
248 r_delete_entry (DestroyTarget
->element_tree
, (BoxType
*) Element
);
249 if (DestroyTarget
->pin_tree
)
253 r_delete_entry (DestroyTarget
->pin_tree
, (BoxType
*) pin
);
257 if (DestroyTarget
->pad_tree
)
261 r_delete_entry (DestroyTarget
->pad_tree
, (BoxType
*) pad
);
265 ELEMENTTEXT_LOOP (Element
);
267 if (DestroyTarget
->name_tree
[n
])
268 r_delete_entry (DestroyTarget
->name_tree
[n
], (BoxType
*) text
);
271 FreeElementMemory (Element
);
272 if (Element
!= &DestroyTarget
->Element
[--DestroyTarget
->ElementN
])
274 *Element
= DestroyTarget
->Element
[DestroyTarget
->ElementN
];
275 /* deal with changed element pointer */
276 r_substitute (DestroyTarget
->element_tree
,
277 (BoxType
*) & DestroyTarget
->Element
[DestroyTarget
->
279 (BoxType
*) Element
);
283 pin
->Element
= Element
;
288 pad
->Element
= Element
;
291 ELEMENTTEXT_LOOP (Element
);
293 r_substitute (DestroyTarget
->name_tree
[n
],
294 (BoxType
*) & DestroyTarget
->Element
[DestroyTarget
->
297 text
->Element
= Element
;
300 memset (&DestroyTarget
->Element
[DestroyTarget
->ElementN
], 0,
301 sizeof (ElementType
));
305 /* ---------------------------------------------------------------------------
309 DestroyRat (RatTypePtr Rat
)
311 if (DestroyTarget
->rat_tree
)
312 r_delete_entry (DestroyTarget
->rat_tree
, &Rat
->BoundingBox
);
313 if (Rat
!= &DestroyTarget
->Rat
[--DestroyTarget
->RatN
])
315 *Rat
= DestroyTarget
->Rat
[DestroyTarget
->RatN
];
316 r_substitute (DestroyTarget
->rat_tree
,
317 &DestroyTarget
->Rat
[DestroyTarget
->RatN
].BoundingBox
,
320 memset (&DestroyTarget
->Rat
[DestroyTarget
->RatN
], 0, sizeof (RatType
));
325 /* ---------------------------------------------------------------------------
329 RemoveVia (PinTypePtr Via
)
331 /* erase from screen and memory */
338 MoveObjectToRemoveUndoList (VIA_TYPE
, Via
, Via
, Via
);
342 /* ---------------------------------------------------------------------------
346 RemoveRat (RatTypePtr Rat
)
348 /* erase from screen and memory */
355 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
366 remove_point (const BoxType
* b
, void *cl
)
368 LineType
*line
= (LineType
*) b
;
369 struct rlp_info
*info
= (struct rlp_info
*) cl
;
370 if (line
== info
->line
)
372 if ((line
->Point1
.X
== info
->point
->X
)
373 && (line
->Point1
.Y
== info
->point
->Y
))
376 info
->point
= &line
->Point1
;
377 longjmp (info
->env
, 1);
380 if ((line
->Point2
.X
== info
->point
->X
)
381 && (line
->Point2
.Y
== info
->point
->Y
))
384 info
->point
= &line
->Point2
;
385 longjmp (info
->env
, 1);
390 /* ---------------------------------------------------------------------------
391 * removes a line point, or a line if the selected point is the end
394 RemoveLinePoint (LayerTypePtr Layer
, LineTypePtr Line
, PointTypePtr Point
)
397 struct rlp_info info
;
398 if (&Line
->Point1
== Point
)
399 other
= Line
->Point2
;
401 other
= Line
->Point1
;
404 if (setjmp (info
.env
) == 0)
406 r_search (Layer
->line_tree
, (const BoxType
*) Point
, NULL
, remove_point
,
408 return RemoveLine (Layer
, Line
);
410 MoveObject (LINEPOINT_TYPE
, Layer
, info
.line
, info
.point
,
411 other
.X
- Point
->X
, other
.Y
- Point
->Y
);
412 return (RemoveLine (Layer
, Line
));
415 /* ---------------------------------------------------------------------------
416 * removes a line from a layer
419 RemoveLine (LayerTypePtr Layer
, LineTypePtr Line
)
421 /* erase from screen */
428 MoveObjectToRemoveUndoList (LINE_TYPE
, Layer
, Line
, Line
);
432 /* ---------------------------------------------------------------------------
433 * removes an arc from a layer
436 RemoveArc (LayerTypePtr Layer
, ArcTypePtr Arc
)
438 /* erase from screen */
445 MoveObjectToRemoveUndoList (ARC_TYPE
, Layer
, Arc
, Arc
);
449 /* ---------------------------------------------------------------------------
450 * removes a text from a layer
453 RemoveText (LayerTypePtr Layer
, TextTypePtr Text
)
455 /* erase from screen */
458 EraseText (Layer
, Text
);
462 MoveObjectToRemoveUndoList (TEXT_TYPE
, Layer
, Text
, Text
);
466 /* ---------------------------------------------------------------------------
467 * removes a polygon from a layer
470 RemovePolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
472 /* erase from screen */
475 ErasePolygon (Polygon
);
479 MoveObjectToRemoveUndoList (POLYGON_TYPE
, Layer
, Polygon
, Polygon
);
483 /* ---------------------------------------------------------------------------
484 * removes a polygon-point from a polygon
487 RemovePolygonPoint (LayerTypePtr Layer
,
488 PolygonTypePtr Polygon
, PointTypePtr Point
)
492 if (Polygon
->PointN
<= 3)
493 return RemovePolygon (Layer
, Polygon
);
495 ErasePolygon (Polygon
);
496 /* insert the polygon-point into the undo list */
497 POLYGONPOINT_LOOP (Polygon
);
506 AddObjectToRemovePointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
, index
);
507 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
508 /* remove point from list, keep point order */
509 for (ptr
= Point
+ 1; ptr
!= &Polygon
->Points
[Polygon
->PointN
]; ptr
++)
515 SetPolygonBoundingBox (Polygon
);
516 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
517 RemoveExcessPolygonPoints (Layer
, Polygon
);
518 InitClip (PCB
->Data
, Layer
, Polygon
);
519 /* redraw polygon if necessary */
522 DrawPolygon (Layer
, Polygon
, 0);
529 /* ---------------------------------------------------------------------------
533 RemoveElement (ElementTypePtr Element
)
535 /* erase from screen */
536 if ((PCB
->ElementOn
|| PCB
->PinOn
) &&
537 (FRONT (Element
) || PCB
->InvisibleObjectsOn
))
539 EraseElement (Element
);
543 MoveObjectToRemoveUndoList (ELEMENT_TYPE
, Element
, Element
, Element
);
547 /* ----------------------------------------------------------------------
548 * removes all selected and visible objects
549 * returns True if any objects have been removed
552 RemoveSelected (void)
555 if (SelectedOperation (&RemoveFunctions
, False
, ALL_TYPES
))
557 IncrementUndoSerialNumber ();
566 /* ---------------------------------------------------------------------------
567 * remove object as referred by pointers and type,
568 * allocated memory is passed to the 'remove undo' list
571 RemoveObject (int Type
, void *Ptr1
, void *Ptr2
, void *Ptr3
)
573 void *ptr
= ObjectOperation (&RemoveFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
577 /* ---------------------------------------------------------------------------
578 * DeleteRats - deletes rat lines only
579 * can delete all rat lines, or only selected one
583 DeleteRats (Boolean selected
)
585 Boolean changed
= False
;
587 RAT_LOOP (PCB
->Data
);
589 if ((!selected
) || TEST_FLAG (SELECTEDFLAG
, line
))
600 IncrementUndoSerialNumber ();
605 /* ---------------------------------------------------------------------------
606 * remove object as referred by pointers and type
607 * allocated memory is destroyed assumed to already be erased
610 DestroyObject (DataTypePtr Target
, int Type
, void *Ptr1
,
611 void *Ptr2
, void *Ptr3
)
613 DestroyTarget
= Target
;
614 return (ObjectOperation (&DestroyFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
));