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 *Via
= DestroyTarget
->Via
[--DestroyTarget
->ViaN
];
134 r_substitute (DestroyTarget
->via_tree
, (BoxTypePtr
)
135 (BoxType
*) & DestroyTarget
->Via
[DestroyTarget
->ViaN
],
137 memset (&DestroyTarget
->Via
[DestroyTarget
->ViaN
], 0, sizeof (PinType
));
141 /* ---------------------------------------------------------------------------
142 * destroys a line from a layer
145 DestroyLine (LayerTypePtr Layer
, LineTypePtr Line
)
147 r_delete_entry (Layer
->line_tree
, (BoxTypePtr
) Line
);
148 MYFREE (Line
->Number
);
149 *Line
= Layer
->Line
[--Layer
->LineN
];
150 /* tricky - line pointers are moved around */
151 r_substitute (Layer
->line_tree
, (BoxType
*) & Layer
->Line
[Layer
->LineN
],
153 memset (&Layer
->Line
[Layer
->LineN
], 0, sizeof (LineType
));
157 /* ---------------------------------------------------------------------------
158 * destroys an arc from a layer
161 DestroyArc (LayerTypePtr Layer
, ArcTypePtr Arc
)
163 r_delete_entry (Layer
->arc_tree
, (BoxTypePtr
) Arc
);
164 *Arc
= Layer
->Arc
[--Layer
->ArcN
];
165 r_substitute (Layer
->arc_tree
, (BoxType
*) & Layer
->Arc
[Layer
->ArcN
],
167 memset (&Layer
->Arc
[Layer
->ArcN
], 0, sizeof (ArcType
));
171 /* ---------------------------------------------------------------------------
172 * destroys a polygon from a layer
175 DestroyPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
177 r_delete_entry (Layer
->polygon_tree
, (BoxTypePtr
) Polygon
);
178 FreePolygonMemory (Polygon
);
179 *Polygon
= Layer
->Polygon
[--Layer
->PolygonN
];
180 r_substitute (Layer
->polygon_tree
,
181 (BoxType
*) & Layer
->Polygon
[Layer
->PolygonN
],
182 (BoxType
*) Polygon
);
183 memset (&Layer
->Polygon
[Layer
->PolygonN
], 0, sizeof (PolygonType
));
187 /* ---------------------------------------------------------------------------
188 * removes a polygon-point from a polygon and destroys the data
191 DestroyPolygonPoint (LayerTypePtr Layer
,
192 PolygonTypePtr Polygon
, PointTypePtr Point
)
196 if (Polygon
->PointN
<= 3)
197 return RemovePolygon(Layer
, Polygon
);
198 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
199 for (ptr
= Point
+ 1; ptr
!= &Polygon
->Points
[Polygon
->PointN
]; ptr
++)
205 SetPolygonBoundingBox (Polygon
);
206 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
207 InitClip (PCB
->Data
, Layer
, Polygon
);
211 /* ---------------------------------------------------------------------------
212 * destroys a text from a layer
215 DestroyText (LayerTypePtr Layer
, TextTypePtr Text
)
217 MYFREE (Text
->TextString
);
218 r_delete_entry (Layer
->text_tree
, (BoxTypePtr
) Text
);
219 *Text
= Layer
->Text
[--Layer
->TextN
];
220 r_substitute (Layer
->text_tree
, (BoxType
*) & Layer
->Text
[Layer
->TextN
],
222 memset (&Layer
->Text
[Layer
->TextN
], 0, sizeof (TextType
));
226 /* ---------------------------------------------------------------------------
230 DestroyElement (ElementTypePtr Element
)
232 if (DestroyTarget
->element_tree
)
233 r_delete_entry (DestroyTarget
->element_tree
, (BoxType
*) Element
);
234 if (DestroyTarget
->pin_tree
)
238 r_delete_entry (DestroyTarget
->pin_tree
, (BoxType
*) pin
);
242 if (DestroyTarget
->pad_tree
)
246 r_delete_entry (DestroyTarget
->pad_tree
, (BoxType
*) pad
);
250 ELEMENTTEXT_LOOP (Element
);
252 if (DestroyTarget
->name_tree
[n
])
253 r_delete_entry (DestroyTarget
->name_tree
[n
], (BoxType
*) text
);
256 FreeElementMemory (Element
);
257 *Element
= DestroyTarget
->Element
[--DestroyTarget
->ElementN
];
258 /* deal with changed element pointer */
259 r_substitute (DestroyTarget
->element_tree
,
260 (BoxType
*) & DestroyTarget
->Element
[DestroyTarget
->ElementN
],
261 (BoxType
*) Element
);
264 pin
->Element
= Element
;
269 pad
->Element
= Element
;
272 ELEMENTTEXT_LOOP (Element
);
274 r_substitute (DestroyTarget
->name_tree
[n
],
275 (BoxType
*) & DestroyTarget
->Element
[DestroyTarget
->
278 text
->Element
= Element
;
281 memset (&DestroyTarget
->Element
[DestroyTarget
->ElementN
], 0,
282 sizeof (ElementType
));
286 /* ---------------------------------------------------------------------------
290 DestroyRat (RatTypePtr Rat
)
292 if (DestroyTarget
->rat_tree
)
293 r_delete_entry (DestroyTarget
->rat_tree
, &Rat
->BoundingBox
);
294 *Rat
= DestroyTarget
->Rat
[--DestroyTarget
->RatN
];
295 r_substitute (DestroyTarget
->rat_tree
,
296 &DestroyTarget
->Rat
[DestroyTarget
->RatN
].BoundingBox
,
298 memset (&DestroyTarget
->Rat
[DestroyTarget
->RatN
], 0, sizeof (RatType
));
303 /* ---------------------------------------------------------------------------
307 RemoveVia (PinTypePtr Via
)
309 /* erase from screen and memory */
316 MoveObjectToRemoveUndoList (VIA_TYPE
, Via
, Via
, Via
);
320 /* ---------------------------------------------------------------------------
324 RemoveRat (RatTypePtr Rat
)
326 /* erase from screen and memory */
333 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
345 remove_point (const BoxType
* b
, void *cl
)
347 LineType
*line
= (LineType
*) b
;
348 struct rlp_info
*info
= (struct rlp_info
*) cl
;
350 if (line
== info
->line
)
352 if ((line
->Point1
.X
== info
->point
->X
)
353 && (line
->Point1
.Y
== info
->point
->Y
))
356 info
->point
= &line
->Point1
;
357 longjmp (info
->env
, 1);
359 else if ((line
->Point2
.X
== info
->point
->X
)
360 && (line
->Point2
.Y
== info
->point
->Y
))
363 info
->point
= &line
->Point2
;
364 longjmp (info
->env
, 1);
369 /* ---------------------------------------------------------------------------
370 * removes a line point, or a line if the selected point is the end
373 RemoveLinePoint (LayerTypePtr Layer
, LineTypePtr Line
, PointTypePtr Point
)
376 struct rlp_info info
;
378 if (&Line
->Point1
== Point
)
379 other
= Line
->Point2
;
381 other
= Line
->Point1
;
384 if (setjmp (info
.env
) == 0)
386 r_search (Layer
->line_tree
, (const BoxType
*) Point
, NULL
, remove_point
,
388 return RemoveLine(Layer
, Line
);
390 MoveObject (LINEPOINT_TYPE
, Layer
, info
.line
, info
.point
,
391 other
.X
- Point
->X
, other
.Y
- Point
->Y
);
392 return (RemoveLine (Layer
, Line
));
395 /* ---------------------------------------------------------------------------
396 * removes a line from a layer
399 RemoveLine (LayerTypePtr Layer
, LineTypePtr Line
)
401 /* erase from screen */
408 MoveObjectToRemoveUndoList (LINE_TYPE
, Layer
, Line
, Line
);
412 /* ---------------------------------------------------------------------------
413 * removes an arc from a layer
416 RemoveArc (LayerTypePtr Layer
, ArcTypePtr Arc
)
418 /* erase from screen */
425 MoveObjectToRemoveUndoList (ARC_TYPE
, Layer
, Arc
, Arc
);
429 /* ---------------------------------------------------------------------------
430 * removes a text from a layer
433 RemoveText (LayerTypePtr Layer
, TextTypePtr Text
)
435 /* erase from screen */
438 EraseText (Layer
, Text
);
442 MoveObjectToRemoveUndoList (TEXT_TYPE
, Layer
, Text
, Text
);
446 /* ---------------------------------------------------------------------------
447 * removes a polygon from a layer
450 RemovePolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
452 /* erase from screen */
455 ErasePolygon (Polygon
);
459 MoveObjectToRemoveUndoList (POLYGON_TYPE
, Layer
, Polygon
, Polygon
);
463 /* ---------------------------------------------------------------------------
464 * removes a polygon-point from a polygon
467 RemovePolygonPoint (LayerTypePtr Layer
,
468 PolygonTypePtr Polygon
, PointTypePtr Point
)
473 if (Polygon
->PointN
<= 3)
474 return RemovePolygon(Layer
, Polygon
);
476 ErasePolygon (Polygon
);
477 /* insert the polygon-point into the undo list */
478 POLYGONPOINT_LOOP (Polygon
);
488 AddObjectToRemovePointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
, index
);
489 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
491 /* remove point from list, keep point order */
492 for (ptr
= Point
+ 1; ptr
!= &Polygon
->Points
[Polygon
->PointN
]; ptr
++)
498 SetPolygonBoundingBox (Polygon
);
499 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
500 RemoveExcessPolygonPoints (Layer
, Polygon
);
501 InitClip (PCB
->Data
, Layer
, Polygon
);
502 /* redraw polygon if necessary */
505 DrawPolygon (Layer
, Polygon
, 0);
512 /* ---------------------------------------------------------------------------
516 RemoveElement (ElementTypePtr Element
)
518 /* erase from screen */
519 if ((PCB
->ElementOn
|| PCB
->PinOn
) &&
520 (FRONT (Element
) || PCB
->InvisibleObjectsOn
))
522 EraseElement (Element
);
526 MoveObjectToRemoveUndoList (ELEMENT_TYPE
, Element
, Element
, Element
);
530 /* ----------------------------------------------------------------------
531 * removes all selected and visible objects
532 * returns True if any objects have been removed
535 RemoveSelected (void)
538 if (SelectedOperation (&RemoveFunctions
, False
, ALL_TYPES
))
540 IncrementUndoSerialNumber ();
549 /* ---------------------------------------------------------------------------
550 * remove object as referred by pointers and type,
551 * allocated memory is passed to the 'remove undo' list
554 RemoveObject (int Type
, void *Ptr1
, void *Ptr2
, void *Ptr3
)
556 void *ptr
= ObjectOperation (&RemoveFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
560 /* ---------------------------------------------------------------------------
561 * DeleteRats - deletes rat lines only
562 * can delete all rat lines, or only selected one
566 DeleteRats (Boolean selected
)
568 Boolean changed
= False
;
571 RAT_LOOP (PCB
->Data
);
573 if ((!selected
) || TEST_FLAG (SELECTEDFLAG
, line
))
584 IncrementUndoSerialNumber ();
589 /* ---------------------------------------------------------------------------
590 * remove object as referred by pointers and type
591 * allocated memory is destroyed assumed to already be erased
594 DestroyObject (DataTypePtr Target
, int Type
, void *Ptr1
, void *Ptr2
,
597 DestroyTarget
= Target
;
598 return (ObjectOperation (&DestroyFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
));